LeetCode 39. Combination Sum and LeetCode 40. Combination Sum II

【题目 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:

  • All numbers (including target) will be positive integers.
  • The solution set must not contain duplicate combinations.

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& path。

参数解释:

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:

  • All numbers (including target) will be positive integers.
  • The solution set must not contain duplicate combinations.

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;
        }
    }


你可能感兴趣的:(递归)