[leetcode]40. Combination Sum II ,python实现【medium难度】

该博客探讨了LeetCode中的40题组合总和II,要求找到所有候选数C中唯一且不重复的组合,使得它们的和等于目标数T。博主分享了一种Python解决方案,通过使用一个标志列表来跟踪每个数字是否已使用过,并特别处理了存在重复数字的情况,以避免生成重复组合。文章提供了详细的解题思路和示例解答。
摘要由CSDN通过智能技术生成

题目

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]
]

http://blog.csdn.net/zl87758539/article/details/51693179类似是它的衍生题目:

区别在哪里呢,首先只能用一次,我想到的办法是加入一个flaglist,如果用过标记为1,没用过标记为0。
以后碰到的时候不管什么时候只要为1就跳过。

不仅还有,还有个问题是,比如这个题目[1,1,…..],两个1 的时候,如果都处理,那么肯定会得到两组一样的结果。
所以这种情况下要排除,在递归的时候,到了这里,需要处理一下。

代码:

class Solution(object):
    def combinationSum2(self, candidates, target):
        """
        :type candidates: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        self.resList = []
        fl = [0]*len(candidates)
        candidates = sorted(candidates)#排个序不影响复杂度
        self.dfs(candidates,[],target,fl,0)
        return self.resList
    def dfs(self, candidates, sublist, target, flaglist, last):
        if target == 0:
            self.resList.append(sublist[:])
        if target< candidates[0]:
            return 
        l = None #为了防止重复的比如两个1,那在一层递归只处理一次
        for m in range(len(candidates)):
            n = candidates[m] 
            if n > target:
                return
            if n < last or flaglist[m]==1 or l ==n: 
                #三种情况:1.因为是从小到大,所以n开始要从上一个数以后,
                #2.如果已经使用过,那就继续
                #3.如果在这一层递归的时候 比如有两个1, 那之前做一次1的时候,第二次就不处理了,不然会重复
                continue
            sublist.append(n)
            flaglist[m] = 1 #记录是否 用过的
            self.dfs(candidates,sublist,target - n,flaglist, n)
            flaglist[m] = 0
            l = n
            sublist.pop()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值