链接
39. 组合总和
题目
给你一个 无重复元素 的整数数组?candidates 和一个目标整数?target?,找出?candidates?中可以使数字和为目标数?target 的 所有?不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。?
对于给定的输入,保证和为?target 的不同组合数少于 150 个。
示例
示例?1: 输入:candidates = [2,3,6,7], target = 7 输出:[[2,2,3],[7]] 解释: 2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。 7 也是一个候选, 7 = 7 。 仅有这两种组合。
示例?2: 输入: candidates = [2,3,5], target = 8 输出: [[2,2,2,2],[2,3,3],[3,5]]
示例 3: 输入: candidates = [2], target = 1 输出: []
说明
- 1 <= candidates.length <= 30
- 1 <= candidates[i] <= 200
- candidate 中的每个元素都 互不相同
- 1 <= target <= 500
思路
这题很明显采用回溯搜索,遍历每种情况,cur表示当前数组,cursum表示当前数组中所有元素的和,index则表示当前遍历的数组下标,遇到满足条件的cur数组则存入res当中。
C++ Code
class Solution {
public:
vector<vector<int>> res;
vector<int> cur;
void backtracking(vector<int>& candidates, int target, int cursum,int index){
if(cursum==target) {res.push_back(cur); return;}
if(cursum>target || index>=candidates.size()) return;
int n=candidates[index];
for(int j=0;j<=(target-cursum)/n;j++)
{
for(int k=1;k<=j;k++) cur.push_back(n);
cursum+=n*j;
backtracking(candidates,target,cursum,index+1);
cursum-=n*j;
for(int k=1;k<=j;k++) cur.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
backtracking(candidates, target, 0, 0);
return res;
}
};
另外,同样的思路,本题还有另一种写法。
class Solution {
public:
vector<vector<int>> res;
vector<int> cur;
void backtracking(vector<int>& candidates, int target, int cursum,int index){
if(cursum==target) {res.push_back(cur); return;}
if(cursum>target) return;
for(int i=index;i<candidates.size();i++)
{
int n=candidates[i];
cur.push_back(n);
cursum+=n;
backtracking(candidates,target,cursum,i);
cursum-=n;
cur.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
backtracking(candidates, target, 0, 0);
return res;
}
};
|