LeetCode #40 Combination Sum II

题目

Combination Sum II


解题方法

这题也是典型的排列组合问题,可参考Combination Sum

需要注意的是这道题规定:

  1. 每个组合不允许重复使用同一位的元素;
  2. 返回值中不允许出现重复的组合,比如[1, 1, 6]和[1, 6, 1]就是重复的组合。

因此我对应地做了两个调整:

  1. 修改dfs递归调用时传递的candidate下标为i+1,跳过当前位置;
  2. 返回之前对嵌套列表ret进行去重操作,去重方法:3Sum

但实际上可以在dfs的循环体中加一行判断代码,实现在处理过程中去重,省去最后的去重操作,能够显著降低运行时间:

if i > 0 and candidates[i] == candidates[i-1]: continue

代码

返回之前去重

class Solution:
    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        ret = []
        candidates.sort()
        self.dfs(candidates, target, [], ret)
        
        temp_set = set(tuple(i) for i in ret)
        new_list = [list(t) for t in temp_set]
        
        return new_list
    
    def dfs(self, candidates: List[int], target: int, path: List[int], ret: List[List[int]]):
        if target < 0:
            return
        if target == 0:
            ret.append(path)
            return
        for i in range(len(candidates)):
            if candidates[i] > target:
                break
            self.dfs(candidates[i+1:], target-candidates[i], path+[candidates[i]], ret)

处理过程中去重

class Solution:
    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        ret = []
        candidates.sort()
        self.dfs(candidates, target, [], ret)
        return ret
    
    def dfs(self, candidates: List[int], target: int, path: List[int], ret: List[List[int]]):
        if target < 0:
            return
        if target == 0:
            ret.append(path)
            return
        for i in range(len(candidates)):
            if candidates[i] > target:
                break
            if i > 0 and candidates[i] == candidates[i-1]:
                continue
            self.dfs(candidates[i+1:], target-candidates[i], path+[candidates[i]], ret)
posted @ 2020-10-12 11:11  老鼠司令  阅读(44)  评论(0编辑  收藏  举报