39. 组合总和
本题是 集合里元素可以用无数次,那么和组合问题的差别 其实仅在于 startIndex上的控制
class Solution:
def backtracking(self,candidates,target,result,path,sum,startIndex):
if sum>target:
return
if sum==target:
result.append(path[:])
for i in range(startIndex,len(candidates)):
path.append(candidates[i])
sum+=candidates[i]
self.backtracking(candidates,target,result,path,sum,i)
sum-=candidates[i]
path.pop()
return result
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
result=[]
result=self.backtracking(candidates,target,result,[],0,0)
return result
40.组合总和II
这个去重还挺麻烦的,主要问题在于想不到去使用一个used数组去控制树层去重和树枝去重
本题的难点在于区别2中:集合(数组candidates)有重复元素,但还不能有重复的组合。
都知道组合问题可以抽象为树形结构,那么“使用过”在这个树形结构上是有两个维度的:
- 一个维度是同一树枝上使用过
- 一个维度是同一树层上使用过
- 强调一下,树层去重的话,需要对数组排序!
class Solution:
def backtracking(self,candidates,target,result,path,sum,startIndex,used):
if sum==target:
result.append(path[:])
for i in range(startIndex,len(candidates)):
if sum+candidates[i]>target:
break
if i>startIndex and candidates[i]==candidates[i-1] and used[i-1]==0:
continue
path.append(candidates[i])
used[i]=1
sum+=candidates[i]
self.backtracking(candidates,target,result,path,sum,i+1,used)
sum-=candidates[i]
path.pop()
used[i]=0
return result
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
result=[]
candidates.sort()
length=len(candidates)
used=[0]*length
result=self.backtracking(candidates,target,result,[],0,0,used)
return result
131.分割回文串
class Solution:
def is_palindrome(self,s,start,end):
i=start
j=end
while i<j:
if s[i]!=s[j]:
return False
i+=1
j-=1
return True
def backtracking(self,s,result,path,startIndex):
if startIndex==len(s):
result.append(path[:])
return
# if startIndex>len(s):
# return
for i in range(startIndex,len(s)):
if self.is_palindrome(s,startIndex,i):
path.append(s[startIndex:i+1])
self.backtracking(s,result,path,i+1)
path.pop()
def partition(self, s: str) -> List[List[str]]:
path=[]
result=[]
self.backtracking(s,result,path,0)
return result