代码随想录 - Day32 - 回溯:组合问题
39. 组合总和
做题的时候遇到一点疑问:
为什么必须是result.append(path[:])
而不能写成result.append(path)
呢?
原因:
result.append(path)
往result
中添加的是path
这个参数,后续如果path
发生改变,那么result
中的值也会跟着一起发生改变。
result.append(path[:])
是把一个新的list
添加到result
中,后续path
的改变不会影响result
中的值。
class Solution:def backtracking(self, startIndex, currentSum, path, result, target, candidates):if currentSum > target:returnif currentSum == target:result.append(path[:]) # 必须是 result.append(path[:])returnfor i in range(startIndex, len(candidates)):currentSum += candidates[i]path.append(candidates[i])self.backtracking(i, currentSum, path, result, target,candidates)currentSum -= candidates[i]path.pop()def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:result = []self.backtracking(0, 0, [], result, target, candidates)return result
想到了怎么剪枝但是代码一直写不到一块,看了题解才知道应该写到 for 循环里
lass Solution:def backtracking(self, startIndex, currentSum, path, result, target, candidates):if currentSum > target:returnif currentSum == target:result.append(path[:])returnfor i in range(startIndex, len(candidates)):if currentSum + candidates[startIndex] > target: # 剪枝returncurrentSum += candidates[i]path.append(candidates[i])self.backtracking(i, currentSum, path, result, target,candidates)currentSum -= candidates[i]path.pop() def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:result = []candidates.sort() # 必须给 candidates 排序一下,因为题目中并没有说 candidates 中元素是按照从小到大的顺序的self.backtracking(0, 0, [], result, target, candidates)return result
40. 组合总和 II
要想到的问题:
candidates
中的元素并非有序 好解决,用sort()
就可以了
candidates
中的元素可以重复,重复元素会出现相同path
,要排除该情况 卡在这一步了
这道题在去重的地方有些复杂,画个图:
candidates = [1,1,2]
target = 3
虚线的部分是没有遍历的,画出来只是为了更方便理解。
从图中可以直观的看出,要去重的是同一树层上相同的元素,而不是同一树枝上相同的元素的
class Solution:def backtracking(self, startIndex, currentSum, target, candidates, result, path):if currentSum > target:returnif currentSum == target:result.append(path[:])returnfor i in range(startIndex, len(candidates)):if currentSum + candidates[i] > target: # 剪枝return# 对同一树层使用过的元素进行跳过if i > startIndex and candidates[i - 1] == candidates[i]:continuecurrentSum += candidates[i]path.append(candidates[i])self.backtracking(i + 1, currentSum, target, candidates, result, path)currentSum -= candidates[i]path.pop()def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:candidates.sort() # 排序result = []self.backtracking(0, 0, target, candidates, result, [])return result
今天第二道题用了好长时间,这种题怎么能是中等?!