39. 组合总和
给你一个 无重复元素 的整数数组 candidates
和一个目标整数 target
,找出 candidates
中可以使数字和为目标数 target
的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates
中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target
的不同组合数少于 150
个。
解决方法
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
ans = []
path = []
def dfs(i: int, left: int) -> None:
if left == 0:
# 找到一个合法组合
ans.append(path.copy())
return
if i == len(candidates) or left < 0:
return
# 不选
dfs(i + 1, left)
# 选
path.append(candidates[i])
dfs(i, left - candidates[i])
path.pop() # 恢复现场
dfs(0, target)
return ans
40.组合总和II
给定一个候选人编号的集合 candidates
和一个目标数 target
,找出 candidates
中所有可以使数字和为 target
的组合。
candidates
中的每个数字在每个组合中只能使用 一次 。
注意:解集不能包含重复的组合。
解决方法
class Solution:
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
n = len(candidates)
ans = []
path = []
candidates.sort()
def dfs(i, curr):
if curr == 0:
ans.append(path[:])
return
for j in range(i, n):
if j > i and candidates[j] == candidates[j-1]:#跳过相同元素
continue
if curr < candidates[i]: #剪枝
break
path.append(candidates[j])
dfs(j+1, curr-candidates[j])
path.pop()
dfs(0, target)
return ans
131.分割回文串
给你一个字符串 s
,请你将 s
分割成一些子串,使每个子串都是 回文串。返回 s
所有可能的分割方案。
解决方法
class Solution:
def partition(self, s: str) -> List[List[str]]:
ans = []
path = []
n = len(s)
# start 表示当前这段回文子串的开始位置
def dfs(i: int, start: int) -> None:
if i == n:
ans.append(path.copy()) # 复制 path
return
# 不选 i 和 i+1 之间的逗号(i=n-1 时一定要选)
if i < n - 1:
dfs(i + 1, start)
# 选 i 和 i+1 之间的逗号(把 s[i] 作为子串的最后一个字符)
t = s[start: i + 1]
if t == t[::-1]: # 判断是否回文
path.append(t)
dfs(i + 1, i + 1) # 下一个子串从 i+1 开始
path.pop() # 恢复现场
dfs(0, 0)
return ans