LC39. 组合总和
class Solution:
def __init__(self):
self.path = []
self.res = []
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
self.backtracking(candidates, target, 0 ,0)
return self.res
def backtracking(self, candidates: List[int], target: int, sum_: int, startindex: int) -> None:
if sum_ == target:
self.res.append(self.path[:])
return
if sum_ > target:
return #两个终止条件:1.当sum值等于target时,说明找到了要求的path,将结果加到res里返回。2.当sum值大于target, 不符合要求,直接返回
for i in range(startindex, len(candidates)):
self.path.append(candidates[i])
sum_ += candidates[i]
self.backtracking(candidates, target, sum_, i) # 因为无限制重复选取,所以不是i+1
sum_ -= candidates[i]
self.path.pop() #回溯
LC40.组合总和II
class Solution:
def __init__(self):
self.path = []
self.res = []
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
candidates.sort() # 必须提前进行数组排序,避免重复
self.backtracking(candidates, target, 0, 0)
return self.res
def backtracking(self, candidates: List[int], target: int, sum_: int, startindex: int) -> None:
if sum_ == target:
self.res.append(self.path[:])
return
for i in range(startindex, len(candidates)):
if sum_ + candidates[i] > target:
return # 剪枝
if i > startindex and candidates[i] == candidates[i-1]:
continue # 跳过同一树层使用过的元素
self.path.append(candidates[i])
sum_ += candidates[i]
self.backtracking(candidates, target, sum_, i + 1)
sum_ -= candidates[i]
self.path.pop() # 回溯,为了下一轮for loop
LC131.分割回文串:
class Solution:
def __init__(self):
self.path = []
self.res = []
#递归用于纵向遍历 for循环用于横向遍历
#当切割线迭代至字符串末尾,说明找到一种方法类似组合问题,为了不重复切割同一位置,需要start_index来做标记下一轮递归的起始位置(切割线)
def partition(self, s: str) -> List[List[str]]:
self.backtracking(s, 0)
return self.res
def backtracking(self, s: str, startindex: str) -> None:
if startindex >= len(s):
self.res.append(self.path[:])
for i in range(startindex, len(s)):
temp = s[startindex:i+1]
if temp == temp[::-1]: #判断被截取的这一段子串([start_index, i])是否为回文串
self.path.append(temp)
self.backtracking(s, i+1) #递归纵向遍历:从下一处进行切割,判断其余是否仍为回文串
self.path.pop()
else:
continue