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()