题目
思路
回溯算法
不断对每个候选数字进行尝试,遇到以下情况进行回退:
- 已经可以判断不可能再符合条件的时候
- 正好满足条件,可以得出解的时候
如何回溯
在下面的代码中,通过solution数组的solution.pop(),回退上一个尝试的状态
回溯要点
可以看到,回溯算法有两个方面需要注意:
- 什么情况下回退
- 如何回退
复杂度
好像不是很好确定,和具体的candidates和target有很大的关系,如candidates=[1,2,3], target=3000,递归可能很深,因此在这里不进行分析,参考百度,谷歌,StackOverflow
代码
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
# from copy import deepcopy
self.results = []
self.candidates = candidates
self.backtracking(target, 0, [])
return self.results
def backtracking(self, target, start, solution):
if target < 0:
return # 不可能再符合条件,return表示回到上一级递归,进行solution.pop(),将最后一个数字弹出
if target == 0:
self.results.append(copy.deepcopy(solution))
return # 正好满足条件,可以得出解
for i in range(start, len(self.candidates)):
solution.append(self.candidates[i]) # 加入候选
self.backtracking(target - self.candidates[i], i, solution) # 判断是否满足条件
solution.pop() # 回退一步