40. Combination Sum II

40. 组合总和 II

labuladong 题解

难度中等

给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用 一次 。

注意:解集不能包含重复的组合。 

 

示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
输出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]

示例 2:

输入: candidates = [2,5,2,1,2], target = 5,
输出:
[
[1,2,2],
[5]
]

 

提示:

  • 1 <= candidates.length <= 100
  • 1 <= candidates[i] <= 50
  • 1 <= target <= 30
通过次数430,797
 
提交次数720,526

 

class Solution:
    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        candidates = sorted(candidates)
        res = []
        def backtrack(candidates,path,index,cur_sum,target):
            if cur_sum > target:
                return 
            if cur_sum == target:
                res.append(path.copy())
                return
            for i in range(index,len(candidates)):
                if i > index and candidates[i] == candidates[i - 1]:
                    continue
                backtrack(candidates,path+[candidates[i]],i+1,cur_sum+candidates[i],target)
        backtrack(candidates,[],0,0,target)
        return res

 

 

 注意需要排序

 1 class Solution {
 2     private List<List<Integer>> res = new ArrayList<>();
 3     public List<List<Integer>> combinationSum2(int[] candidates, int target) {
 4         List<Integer> temp = new ArrayList<Integer>();
 5         Arrays.sort(candidates);
 6         help(temp,candidates,0,0,target);
 7         return res;
 8     }
 9     private void help(List<Integer> temp,int[] nums,int index,int cursum,int target){
10         if(cursum>target)
11             return;
12         else if(cursum==target)
13             res.add(new ArrayList<Integer>(temp));
14         else{
15             for(int i = index;i<nums.length;i++){
16                 if(i > index && nums[i] == nums[i-1]) continue; // skip duplicates
17                 temp.add(nums[i]);
18                 help(temp,nums,i+1,cursum+nums[i],target);
19                 temp.remove(temp.size()-1);
20             }
21         }
22     }
23 }

 

 

 

 

 

 

 

 

 

 1 class Solution:
 2     def __init__(self):
 3         self.res = []
 4     def combinationSum2(self, candidates, target):
 5         """
 6         :type candidates: List[int]
 7         :type target: int
 8         :rtype: List[List[int]]
 9         """
10         def help(x,temp,index,cursum,t):
11             temp = temp[:]
12             if cursum>t:
13                 return
14             if(cursum==t):
15                 self.res.append(temp)
16             for i in range(index,len(x)):
17                 if(i > index and x[i]==x[i-1]):
18                     continue
19                 temp.append(x[i])
20                 help(x,temp,i+1,cursum +x[i],t)
21                 temp.pop(-1)
22                 
23                 
24         x = sorted(candidates)
25         help(x,[],0,0,target)
26         return self.res
27 
28         

 

 

 

 

与上一个题目不同,这个题要求每个数字只能用一次,

所以需要从i+1开始搜索(代码18行)

candidates 中可能会有重复的元素

[10,1,2,7,6,1,5]
8

 

如果没有19行,结果为

Your answer
[[1,1,6],[1,2,5],[1,7],[1,2,5],[1,7],[2,6]]
Expected answer
[[1,2,5],[1,7],[1,1,6],[2,6]]


因为 1,1,2,5,6,7,10

第一个1会生成结果125,17
第二个1也会生成125,17

 

 

 

2019.3.12

 

 1 class Solution {
 2 public:
 3     vector<vector<int>> finalres ;
 4     vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
 5         if(candidates.size()==0) return finalres;
 6         sort(candidates.begin(),candidates.end());
 7         vector<int> curres;
 8         help(0,curres,candidates,0,target);
 9         return finalres;
10         
11     }
12     void help(int cursum,vector<int>& curres,vector<int>& candidates,int index,int target){
13         if(cursum==target)
14             finalres.push_back(curres);
15         if(cursum>target)
16             return;
17         for(int i = index;i<candidates.size();i++){
18             if(i >index && candidates[i]==candidates[i-1]) continue;
19             curres.push_back(candidates[i]);
20             help(cursum,curres,candidates,i+1,target-candidates[i]);
21             curres.pop_back();
22 
23         }
24     }
25 };

 

posted @ 2018-04-21 17:46  乐乐章  阅读(123)  评论(0编辑  收藏  举报