39. 组合总和
剪枝操作:if summ > target
因为可以重复发使用使用,需要用下标控制起始位置,但避免重复,因此从同一位置往后
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
res = []
path = []
def sumres(j, summ):
if summ > target:
return
if summ == target:
res.append(path[:])
return
for i in range(j, len(candidates)):
path.append(candidates[i])
summ += candidates[i]
sumres(i, summ)
summ -= candidates[i]
path.pop()
sumres(0, 0)
return res
40. 组合总和 II
used 数组的使用:
used[i - 1] == true,说明同一树枝candidates[i - 1]使用过used[i - 1] == false,说明同一树层candidates[i - 1]使用过
同一树层,used[i - 1] == false 才能表示,当前取的 candidates[i] 是从 candidates[i - 1] 回溯而来的。
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
res = []
path = []
used = [False] * len(candidates)
candidates.sort()
# 如何去重
# 添加used数组
def sumres(j, summ):
if summ > target:
return
if summ == target:
res.append(path[:])
return
for i in range(j, len(candidates)):
if i > 0 and candidates[i] == candidates[i-1] and used[i-1] == False:
continue
path.append(candidates[i])
summ += candidates[i]
used[i] = True
sumres(i+1, summ)
used[i] = False
summ -= candidates[i]
path.pop()
sumres(0, 0)
return res
或巧妙利用start_index来跳过
131. 分割回文串
分成 切割+判断回文
注意切割下标的取值
def partition(self, s: str) -> List[List[str]]:
def check(s):
i = 0
j = len(s) - 1
while j > i:
if s[j]!= s[i]:
return False
else:
j -= 1
i += 1
return True
path = []
res = []
def recursion(j):
if j >= len(s):
res.append(path[:])
for i in range(j, len(s)):
sub = s[j:i+1]
if check(sub):
path.append(sub)
recursion(i+1)
path.pop()
recursion(0)
return res