微软面试题: LeetCode 39. 组合总和 出现次数:2

题目描述:

 

 解析:

此类题目 回溯法  相关的题型:排列、组合、子集相关问题

回溯相关问题    可参考 :

https://leetcode-cn.com/problems/permutations/solution/hui-su-suan-fa-python-dai-ma-java-dai-ma-by-liweiw/

解决此类问题需要注意以下几个方面:

1. 需不需要设置 visited 数组:当给定的 candidate 数组中元素不能重复使用时,在 dfs  前进时需要标记和回溯时需取消标记;

2. 需不需要设置 begin 下标:  当题目要求得到的结果 如[1,2,3] 、[2,3,1]、[3,1,2]只能在结果集中存在一个时使用begin 变量,去重并剪枝;

3. 需不需要对给定candidate 数组排序:看剪枝需要,如 本题中的 if(sum + candidate [i] > m_target) break; 就是一个要求排序的剪枝操作;

4.  需不需要跳重复: 当给定candidate  中有重复元素时,需先对 candidate  排序,然后跳重,如 if(i > 0 && candidate[i-1] == candidate[i] && visited[i-1] == 0) continue;

5.需不需要回溯操作:大部分都需要回溯,除非只需要得到一个结果,第一次遍历到对应的叶节点时,就停下,不需要回溯。

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 class Solution {
 4 public:
 5     vector<vector<int>> combinationSum(vector<int>& candidates, int target)
 6     {
 7         m_target = target;
 8         vector<vector<int>> res;
 9         vector<int> path;
10         int sum = 0;
11         std::sort(candidates.begin(),candidates.end());
12         dfs(0,res,path,sum,candidates);
13         return res;
14     }
15 
16     void dfs(int begin,vector<vector<int>> &res,vector<int> &path,int &sum,vector<int>& candidates)
17     {
18         if( sum == m_target)
19         {
20             res.push_back(path);
21             return;
22         }
23         for(int i = begin;i < candidates.size();++i)
24         {
25             if(sum + candidates[i] > m_target)
26             {
27                 break;
28             }
29             sum += candidates[i];
30             path.push_back(candidates[i]);
31             dfs(i,res,path,sum,candidates);
32             sum -= candidates[i];
33             path.pop_back();
34         }
35         return;
36     } 
37 private:
38     int m_target;
39 };

 

posted @ 2021-04-06 18:55  谁在写西加加  阅读(60)  评论(0编辑  收藏  举报