1 leetcode39. 組合總和
題目連結:39. 組合總和 - 力扣(LeetCode)
文章連結:程式碼隨想錄
影片連結:帶你學透回溯演算法-組合總和(對應「leetcode」力扣題目:39.組合總和)| 回溯法精講!_嗶哩嗶哩_bilibili
思路:跟之前差不多,就是將他的迴圈改一下,但是我發現有重複的數值了,不知道如何刪除
1.1 自己的思路
錯誤:
- 基本思路是完全可以實現的,但是有重複的數值,不知道怎麼刪除,但是也就淺淺記錄一下這個方法吧
class Solution:
def __init__(self):
self.result =[]
self.path = []
self.num = 0
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
self.backtracking(candidates,target)
return self.result
def backtracking(self,candidates,target):
if sum(self.path[:])>target:
return
if sum(self.path[:])==target:
self.result.append(self.path[:])
return self.result
for i in range(len(candidates)):
self.path.append(candidates[i])
self.backtracking(candidates,target)
self.path.pop()
1.2 影片的思路
看影片過程中然後反思自己的程式碼,做出來了
原因:索引的起始位置出現了錯誤,更改以後就正確了
class Solution:
def __init__(self):
self.result =[]
self.path = []
self.num = 0
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
self.backtracking(candidates,target,0)
return self.result
def backtracking(self,candidates,target,index):
if sum(self.path[:])>target:
return
if sum(self.path[:])==target:
self.result.append(self.path[:])
return self.result
for i in range(index,len(candidates)):
self.path.append(candidates[i])
self.backtracking(candidates,target,i)
self.path.pop()
1.3 剪枝的方法
class Solution:
def __init__(self):
self.result =[]
self.path = []
self.num = 0
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
self.backtracking(candidates,target,0)
return self.result
def backtracking(self,candidates,target,index):
candidates.sort()
if sum(self.path[:])>target:
return
if sum(self.path[:])==target:
self.result.append(self.path[:])
return self.result
for i in range(index,len(candidates)):
if target-candidates[i]<0:
break
self.path.append(candidates[i])
self.backtracking(candidates,target,i)
self.path.pop()
1.4 本題小結
- 這道題我也算是真正自己做啦,就是當時忘記去重,不知道怎麼加後來自己想了以後也寫出來啦
- 這道題的剪枝方法,我感覺排序會浪費時間,覺得沒有最佳化太多
2 leetcode40.組合總和II
題目連結:40. 組合總和 II - 力扣(LeetCode)
文章連結:程式碼隨想錄
影片連結:回溯演算法中的去重,樹層去重樹枝去重,你弄清楚了沒?| LeetCode:40.組合總和II_嗶哩嗶哩_bilibili
思路:照葫蘆畫瓢,結果發現我翻車了,就是有重複的
2.1 回溯的方法
這裡的判斷條件挺有意思的,從當前位置的後一個去比較,比較他們的值是否有重複的,然後進行去重,確實這個去重是我沒有想到的地方
class Solution:
def __init__(self):
self.result = []
self.path = []
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
candidates.sort()
self.backtracking(candidates,target,0)
return self.result
def backtracking(self,candidates,target,startindex):
if sum(self.path[:])>target:
return
if sum(self.path[:])==target:
self.result.append(self.path[:])
return self.result
for i in range(startindex,len(candidates)):
if i>startindex and candidates[i]==candidates[i-1]:
continue
self.path.append(candidates[i])
self.backtracking(candidates,target,i+1)
self.path.pop()
2.2 使用一個列表的去重方法
這種方法,確實還是自己的資歷不夠很多時候知道要幹啥,但是我確實也寫不出來
class Solution:
def __init__(self):
self.result = []
self.path = []
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
candidates.sort()
used = [False]*len(candidates)
self.backtracking(candidates,target,0,used)
return self.result
def backtracking(self,candidates,target,startindex,used):
if sum(self.path[:])>target:
return
if sum(self.path[:])==target:
self.result.append(self.path[:])
return self.result
for i in range(startindex,len(candidates)):
if i>0 and candidates[i]==candidates[i-1] and used[i-1]==False:
continue
self.path.append(candidates[i])
used[i] =True
self.backtracking(candidates,target,i+1,used)
self.path.pop()
used[i] =False
2.3 本題小結
- 這道題的關鍵點在於去重,對於python去重其實可以保證這個數比當前位置的值大,且與這個數值相等就好了
- 這種used的去重方法,相對而言更適用於所有方法吧
3 leetcode131.分割回文串
題目連結:131. 分割回文串 - 力扣(LeetCode)
文章連結:程式碼隨想錄
影片連結:帶你學透回溯演算法-分割回文串(對應力扣題目:131.分割回文串)| 回溯法精講!_嗶哩嗶哩_bilibili
思路:嗯,就是看不懂吧,,
3.1 影片後的思路
晚上看影片有點暈的感覺,就看講解做了,嗯,覺得自己好懶多定義一個函式都不想,哈哈哈哈哈哈哈,其實定義一個新的函式就可以對其進行一個使用了
class Solution:
def __init__(self):
self.result = []
self.path = []
def partition(self, s: str) -> List[List[str]]:
self.backtracking(s,0)
return self.result
def backtracking(self,s,startindex):
if startindex==len(s):
self.result.append(self.path[:])
return
for i in range(startindex,len(s)):
if self.isPalindrom(s,startindex,i):
self.path.append(s[startindex:i+1])
self.backtracking(s,i+1)
self.path.pop()
def isPalindrom(self,s,left,right):
while left<right:
if s[left]!=s[right]:
return False
left +=1
right-=1
return True
3.2 本題小結
- 這道題,成功被自己的思維打敗了,居然就是多定義一個函式並且在結尾處再對資料進行處理就好了
- 晚上了,不知道寫啥,但是覺得真的不難
4 今日小結
- 第一道題是對之前題目的一個再回顧吧,我覺得剪枝沒有太多的最佳化
- 第二題當時困住我的地方是不知道如何去重,後來發現其實在python中去重的方法挺多的
- 第三題,主要是真的不知道如何分割之類的問題,不過後來好好去思考了,跟著題目也算是可以做了吧