【题目 LeetCode 39】
Given a set of candidate numbers (C) (without duplicates) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
The same repeated number may be chosen from C unlimited number of times.
Note:
For example, given candidate set [2, 3, 6, 7]
and target 7
,
A solution set is:
[
[7],
[2, 2, 3]
]
【题解】
将原数组按从小到大排序,用递归解决该题目。解释下递归函数的一些重要参数int pos, int nSum, vector
参数解释:
1、pos:由于数组的每个数字使用次数无限,所以每次递归for循环的开始下标为上一次递归的位置;当然,回溯后pos的值为数组下一个元素的下标
2、nSum:每次调用递归函数后的数组元素的和,用于判断递归的结束
3、path:记录每次选择的数组元素
同时,在递归的时候我们需要判断如果nSum加上当前选择的数组元素的值大于target的值,那么需要跳出for循环(同时也结束了当前的递归)
【代码】
vector> combinationSum(vector& candidates, int target) {
vector> result;
vector path;
sort(candidates.begin(), candidates.end());
GetResult(candidates, 0, 0, target, path, result);
return result;
}
void GetResult(vector &nums,int pos,int nSum,int target, vector& path, vector>& result) {
if(nSum == target) {
result.push_back(path);
return;
}
for(int i = pos; i < nums.size(); i++) {
if (nSum + nums[i] <= target) {
path.push_back(nums[i]);
GetResult(nums, i, nSum + nums[i], target, path, result);
path.pop_back();
}
else
break;
}
}
【题目 LeetCode 40】
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
Each number in C may only be used once in the combination.
Note:
For example, given candidate set [10, 1, 2, 7, 6, 1, 5]
and target 8
,
A solution set is:
[ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6] ]
【题解】
与LeetCode 39的不同在于数组的元素只能使用一次,切数组存在重复数字,思路相同,需要注意的是:
1、在同一层递归树中,如果某元素已经处理并进入下一层递归,那么与该元素相同的值就应该跳过。否则将出现重复。
例如:1,1,2,3
如果第一个1已经处理并进入下一层递归1,2,3
那么第二个1就应该跳过,因为后续所有情况都已经被覆盖掉。
2、相同元素第一个进入下一层递归,而不是任意一个
例如:1,1,2,3
如果第一个1已经处理并进入下一层递归1,2,3,那么两个1是可以同时成为可行解的
而如果选择的是第二个1并进入下一层递归2,3,那么不会出现两个1的解了
【代码】
vector> combinationSum2(vector& candidates, int target) {
vector> result;
vector path;
sort(candidates.begin(), candidates.end());
GetResult(candidates, 0, 0, target, path, result);
return result;
}
void GetResult(vector &nums,int pos,int nSum,int target, vector& path, vector>& result) {
if(nSum == target) {
result.push_back(path);
return;
}
for(int i = pos; i < nums.size(); i++) {
if (i != pos && nums[i] == nums[i - 1])
continue;
if (nSum + nums[i] <= target) {
path.push_back(nums[i]);
GetResult(nums, i + 1, nSum + nums[i], target, path, result);
path.pop_back();
}
else
break;
}
}