代码随想录算法训练营第23天 | 39.组合总和 40.组合总和Ⅱ 131.分割回文串
39.组合总和
给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target 的不同组合数少于 150 个。
解题
本题和我们之前讲过的77.组合、216.组合总和III有两点不同:
1.组合没有数量要求
2.元素可无限重复选取
报错:1.递归时不用i+1,因为可以重复取;2.回溯忘记处理sum了;
不想看剪枝。。
一个集合里找组合的都要startIndex的哈~
点击查看代码
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
result=[]
self.backtracking(candidates,target,0,0,[],result)
return result
def backtracking(self,candidates,target,sum,startIndex,path,result):
if sum>target:
return
if sum==target:
result.append(path[:])
return
for i in range(startIndex,len(candidates)):
path.append(candidates[i])
sum+=candidates[i]
self.backtracking(candidates,target,sum,i,path,result)
path.pop()
sum-=candidates[i]
40.组合总和Ⅱ
给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用 一次 。
注意:解集不能包含重复的组合。
解题
这道题目和39.组合总和 (opens new window)如下区别:
1.本题candidates 中的每个数字在每个组合中只能使用一次。
2.本题数组candidates的元素是有重复的,而39.组合总和是无重复元素的数组candidates
去重:搜索过程中把同一树层使用过的元素去重,需要对数组排序!!
参数:增加一个bool型参数used
在candidates[i] == candidates[i - 1]相同的情况下:
1.used[i - 1] == true,说明同一树枝candidates[i - 1]使用过
2.used[i - 1] == false,说明同一树层candidates[i - 1]使用过,需要去重这部分!continue跳跳跳过!
if i > startIndex and candidates[i] == candidates[i - 1] and not used[i - 1]:continue
当以上三个条件都满足时,执行 continue 语句,跳过当前循环的剩余部分,直接进入下一次循环。
点击查看代码
class Solution:
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
used=[False]*len(candidates)
result=[]
candidates.sort()
self.backtracking(candidates,target,0,0,used,[],result)
return result
def backtracking(self,candidates,target,sum,startIndex,used,path,result):
if sum>target:
return
if sum==target:
result.append(path[:])
return
for i in range(startIndex,len(candidates)):
if i>startIndex and candidates[i]==candidates[i-1]and not used[i-1]:
continue
sum+=candidates[i]
path.append(candidates[i])
used[i]=True
self.backtracking(candidates,target,sum,i+1,used,path,result)
used[i]=False
path.pop()
sum-=candidates[i]
131.分割回文串
给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是
回文串。返回 s 所有可能的分割方案。
解题
分割线就是startIndex,它也表示递归到哪一层,表示接下来处理的序列是从哪个开始
终止:分割线在最后,startIndex=len(s)
单层递归逻辑:多了个判断s[start_index: i + 1]是否是回文串
if s[start_index: i + 1] == s[start_index: i + 1][::-1]:
点击查看代码
class Solution:
def partition(self, s: str) -> List[List[str]]:
result=[]
self.backtracking(s,0,[],result)
return result
def backtracking(self,s,startIndex,path,result):
if startIndex==len(s):
result.append(path[:])
return
for i in range(startIndex,len(s)):
if s[startIndex:i+1]==s[startIndex:i+1][::-1]:
path.append(s[startIndex:i+1])
self.backtracking(s,i+1,path,result)
path.pop()