day27 代码随想录算法训练营 40. 组合总和 II

题目:40. 组合总和 II

我的感悟:

  • 只要在路上就不怕走的慢。
  • 卡尔的视频慢慢听 0.75倍听还是可以的。
  • 只要状态好,就可以学。
  • 多学会鼓励

理解难点:

  • 去重是本题的难点

代码难点:

  • ① not used[i-1]等同于used[i-1]==0 
  • 这里用的是True和False,所以用的是not used[i-1]
  • ② i > 0 为了防止i-1越界
  • ③ 剪枝为了每次计算剪枝,防止超时。

整理后我改的代码的示例:

class Solution:


    def backtracking(self, candidates, target, total, startIndex, used, path, result):
        if total == target:
            result.append(path[:])
            return

        for i in range(startIndex, len(candidates)):
            # 对于相同的数字,只选择第一个未被使用的数字,跳过其他相同数字
            if i > 0 and candidates[i] == candidates[i - 1] and not used[i - 1] :    # not used[i-1]等同于used[i-1]==0
                continue           

            total += candidates[i]
            if total > target:  # 剪枝操作
                break
            path.append(candidates[i])
            used[i] = True
            self.backtracking(candidates, target, total, i + 1, used, path, result)
            used[i] = False
            total -= candidates[i]
            path.pop()

    def combinationSum2(self, candidates, target):
        used = [False] * len(candidates)
        result = []
        candidates.sort()
        self.backtracking(candidates, target, 0, 0, used, [], result)
        return result

练习1遍:

class Solution:
    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        used = [0] * len(candidates)
        res = []
        candidates.sort()
        self.barktracking(candidates,target,0,0,used,[],res)
        return res
    def barktracking(self,candidates,target,total,startIndex,used,path,res):
        # total 和used参数是后加上的
        # 2.终止条件
        if total == target:
            res.append(path[:])
            return 
        # 1.核心
        for i in range(startIndex,len(candidates)):
            # 3.补充横向剪枝
            if i>0 and candidates[i] == candidates[i-1] and used[i-1] == 0: # 易错点1:是used[i-1]不是used[i],别忘记了
                continue    # 如果横向遍历到一个重复的元素,并且为0,未使用过就跳过
            
           
            total += candidates[i]
            # 4.再补充一个总和的剪枝
            if total > target:
                break   # 如果新的总和已经大于目标值了,就结束本次循环
            path.append(candidates[i])  # 易错点2: 剪枝要放在path前面,因为path是收集路径的结果
            used[i] = 1 # 用过
            self.barktracking(candidates,target,total,i+1,used,path,res)
            path.pop()
            total -= candidates[i]
            used[i] = 0

练习易错点:

  • use[i-1] == 0 不能忘记
  • 剪枝2: total要放在path前面

资料:

题目链接/文章讲解:https://programmercarl.com/0040.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8CII.html

视频讲解:https://www.bilibili.com/video/BV12V4y1V73A

posted @ 2024-02-01 23:09  77gg  阅读(26)  评论(0)    收藏  举报