39. 组合总和
力扣链接
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
思路
class Solution:def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:res = []self.backtracking(candidates, target, 0, 0, [], res)return resdef backtracking(self, candidates, target, cur_sum, startIndex, path, res):if cur_sum > target:returnif cur_sum == target:res.append(path[:]) #一定记得[:]returnfor i in range(startIndex,len(candidates)):cur_sum += candidates[i]path.append(candidates[i])self.backtracking(candidates, target, cur_sum, i, path, res)#startIndex用i表示可以重复读取cur_sum -= candidates[i]path.pop() #回溯
40.组合总和II
力扣链接
给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用 一次 。
注意:解集不能包含重复的组合。
思路
同一层上的相同元素不能重复用,用一个used数组记录每个元素的使用情况。
如果candidates[i] == candidates[i - 1] 并且 used[i - 1] == false,就说明:前一个树枝,使用了candidates[i - 1],也就是说同一树层使用过candidates[i - 1]。
class Solution:def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:used = [False] * len(candidates)res = []candidates.sort()self.backtracking(candidates, target, 0, 0, used, [], res)return resdef backtracking(self, candidates, target, total, startIndex, used, path, res):if total == target:res.append(path[:])returnfor i in range(startIndex, len(candidates)):# 对于相同的数字,只选择第一个未被使用的数字,跳过其他if i > startIndex and candidates[i]==candidates[i-1] and not used[i-1]:continueif total + candidates[i] > target:breaktotal += candidates[i]path.append(candidates[i])used[i] = True #标记为用过self.backtracking(candidates, target, total, i+1, used, path, res)#回溯used[i]=Falsetotal -= candidates[i]path.pop()
131.分割回文串
力扣链接
给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串。返回 s 所有可能的分割方案。
思路
class Solution:def partition(self, s: str) -> List[List[str]]:res = []self.backtracking(s, 0, [], res)return resdef backtracking(self, s, startIndex, path, res):if startIndex == len(s):res.append(path[:])returnfor i in range(startIndex, len(s)):if self.is_palindrome(s, startIndex, i): # 如果是回文path.append(s[startIndex : i+1])self.backtracking(s, i+1, path, res)path.pop()def is_palindrome(self, s, start, end):while start < end:if s[start] != s[end]:return Falsestart += 1end -= 1return True