40. 组合总和 II——回溯去重

这题展示了回溯算法在组合中的优化,需要进行去重操作,可以与上一题17. 电话号码的字母组合对比进行解题。其实,大致的思路差不多,但多了去重的操作。
力扣入口:40. 组合总和 II

套用回溯算法的问题模版,需要确定:

  1. 函数的参数与返回值;
  2. 终止条件;
  3. 单层循环逻辑。
    函数的参数及返回值:

这里, 我们尝试与电话号码字母组合不同的方式,把结果res和路径path当参数传入函数。当然,也可以使用以前的方式写在__init__里面,具体参考这个。因为结果在参数里面,所以不需要返回值。

def combine(self, candidates, target, path, res):

终止条件和上题一样,和大于目标值以及等于目标值时退出。在等于目标值时,意味着找到了一条路径,我们把它放进结果里面。
提醒要使用path[:]把路径拷贝下来,而不是直接用path引用导致结果为[]

 if sum(path) > target: return
 elif sum(path) == target:
     res.append(path[:])
     return

单层for循环需要去重,当后一个数字等于前一个数字的时候,我们跳过。以[1, 1, 7], target = 8为例子,我们在处理第一个1的时候找到了[1, 8]组合,那么在遇到第二个1的时候我们就需要跳过他,避免又找到[1, 8]
很明显,这样的去重方式需要重复元素相邻,所以需要对数组进行排序 candidates. Sort()
博主也尝试了在找到路径之后再进行去重的方式,但是本题超时了,所以还是使用以上的方式。

for index in range(len(candidates)):
    if index != 0 and candidates[index - 1] == candidates[index]:
        continue

    path.append(candidates[index])
    self.combine(candidates[index + 1:], target, path, res)
    path.pop()

总结以上代码:

class Solution:
    def combine(self, candidates, target, path, res):
        if sum(path) > target: return
        elif sum(path) == target:
            res.append(path[:])
            return

        for index in range(len(candidates)):
            if index != 0 and candidates[index - 1] == candidates[index]:
                continue

            path.append(candidates[index])
            self.combine(candidates[index + 1:], target, path, res)
            path.pop()
        return

    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        candidates.sort()
        res = []
        path = []
        self.combine(candidates, target, path, res)
        return res
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值