[leetcode] 40. Combination Sum II

本文探讨了在给定一组候选数和目标数的情况下,如何寻找所有不重复的组合,使得组合中数字之和等于目标数。通过深度优先搜索(DFS)算法,并对输入进行排序来去除重复解,提供了详细的C++和Python代码实现。

Description

Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.

Each number in candidates 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.
    Example 1:
Input: candidates = [10,1,2,7,6,1,5], target = 8,
A solution set is:
[
  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]

Example 2:

Input: candidates = [2,5,2,1,2], target = 5,
A solution set is:
[
  [1,2,2],
  [5]
]

分析

题目的意思是:给你一些候选的数字,然后一个target,找出所有的数字组合等于target的组合。

  • 这是一个DFS题目,经典的遍历方法。

代码一

class Solution {
public:
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        vector<vector<int>> res;
        vector<int> out;
        sort(candidates.begin(),candidates.end());
        dfs(candidates,target,out,0,res);
        return res;
    }
    
    void dfs(vector<int>& candidates,int target,vector<int> out,int start,vector<vector<int>> &res){
        if(target<0){
            return;
        }else if(target==0){
            res.push_back(out);
        }else{
            for(int i=start;i<candidates.size();i++){
                if(i>start&&candidates[i]==candidates[i-1]){
                    continue;
                }
                out.push_back(candidates[i]);
                dfs(candidates,target-candidates[i],out,i+1,res);
                out.pop_back();
            }
        }
    }
};

代码二

class Solution {
public:
    vector<vector<int> > combinationSum2(vector<int> &num, int target) {
        vector<vector<int> > result;
        vector<int> ans;
        sort(num.begin(),num.end());
        int sum=0;
        combinationSum(sum,target,0,ans,num,result);
        return result;
    }
    
    void combinationSum(int sum,int target,int start,vector<int> ans,
                        vector<int> &num,vector<vector<int> > &result){
        if(sum==target){
            vector<vector<int> >::iterator iter;
            iter=find(result.begin(),result.end(),ans);
            if(iter==result.end()){
                result.push_back(ans);
            }
            
            return;
        }
        if(sum>target){
            return;
        }
        for(int i=start;i<num.size();i++){
            ans.push_back(num[i]);
            combinationSum(sum+num[i],target,i+1,ans,num,result);
            ans.pop_back();
        }
    }
};

Python 代码

class Solution:
    def solve(self,cur_sum,index,candidates, target,ans, result):
        if(cur_sum>target):
            return
        elif cur_sum==target:
            result.append([item for item in ans])
    
        for i in range(index,len(candidates),1):
            if(i>index and candidates[i]==candidates[i-1]):
                continue
            ans.append(candidates[i])
            self.solve(cur_sum+candidates[i],i+1,candidates, target,ans,result)
            ans.pop()
        
    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        ans=[]
        result=[]
        candidates.sort()
        self.solve(0,0,candidates,target,ans,result)
        return result

下面是另一种解法,跟上面的写法类似,只是函数的参数会少一点。

class Solution:

    def dfs(self, candidates, start, target, ans, res):
        if sum(ans)==target:
            res.append([item for item in ans])
            return 
        if sum(ans)>target:
            return 
        for i in range(start,len(candidates)):
            if i>start and candidates[i]==candidates[i-1]:
                continue
            ans.append(candidates[i])
            self.dfs(candidates,i+1,target, ans ,res)
            ans.pop()

    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        candidates.sort()
        res = []
        self.dfs(candidates, 0, target, [],res)
        return res

参考文献

[编程题]combination-sum-ii
vector、map 判断某元素是否存在、查找指定元素
[LeetCode] Combination Sum II 组合之和之二

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

农民小飞侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值