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

浙公网安备 33010602011771号