leetcode#22、括號生成
我想到了兩種思路來解決這個問題:
1、先添左括號,沒有左括號,再新增右括號,知道左右括號數量相加等於2倍的n;
然後撤銷並重新新增,直到找出所有組合,如圖所示:
其實就是能進則進,進不了則換,換不了則退->回溯法。
①找返回條件:左括號個數=右括號個數=n或者左括號個數+右括號個數=2*n
②尋找遞迴路徑(重點和難點):遞迴規則,先匹配左括號,沒有左括號再匹配右括號,找到滿足條件的結果加入到結果集;撤銷某些路徑(這對於我來說是理解上的難點),繼續遞迴,執行路徑為1->20。
遞迴引數應該包括:左括號數量(countleft)、右括號數量(countright)、括號的對數(n)、乙個用來記錄結果集的鍊錶和記錄當前結果的字串。
backtrack(int countleft,int countright,int n,list< string>list,stringbuilder str)
錯誤的**:
public list
generateparenthesis
(int n)
/*錯誤的遞迴方法!!!*/
public
void
backtrack
(int countleft,
int countright,
int n,list
ans, stringbuilder str)
while
(countleft
while
(countright
//錯誤點1:while迴圈導致5——>4——>5一直迴圈
//錯誤點2:右括號數量應當比左括號數量少,所以判斷條件應該countright
}
這是我自己犯的錯誤,需要引以為戒:在執行路徑5完成後撤銷,返回路徑4,然後判斷countleft官方的解法)
public
void
backtrack
(int countleft,
int countright,
int n,list
ans, stringbuilder str)
if(countleft
//if判斷保證每個遞迴的函式體只執行一次,不會出現無限迴圈
if(countright
//這裡注意是和「(」的數量作比較
}
具體解釋為什麼countleft++為什麼會是0,最近正好看到一篇文章,i++和++i,可以詳細解答這個問題。
2、確定頭和尾(肯定是『(
』和『)』),在中間確定『(』和『)』的分布情況,而中間仍然會出現頭和尾是『(』和『)』,尋找中間的中間『(』和『)』的分布情況…這就是典型的遞迴問題(我只是產生了這個想法,但沒有寫出來,關於遞迴,我還是太菜了)。直接給出官方答案,我們一起學習:
class
solution
arraylist
ans =
newarraylist()
;if(n ==0)
else
cache[n]
= ans;
return ans;
}public list
generateparenthesis
(int n)
}
發現問題往往能更好的解決問題,共勉 回溯演算法 括號生成
22.括號生成 思路 先用回溯演算法生成所有可能的括號,再判斷生成的括號是否為有效括號。對於有效括號的判斷,leetcode也有一道專門的題,用棧輔助就可以很簡單的解決。整體 也沒啥,就是回溯 有效括號的判斷 class solution def generateparenthesis self,n...
leetcode 生成括號(回溯演算法)
出處 生成括號 給出 n 代表生成括號的對數,請你寫出乙個函式,使其能夠生成所有可能的並且有效的括號組合。例如,給出 n 3,生成結果為 從題目尋找三要素 1 選擇 加左括號 加右括號 2 條件 左括號沒有用完 才可以加左括號 右括號數目小於左括號數目 才可以加右括號 3 結束 左右括號均用完 思路...
回溯演算法最佳實踐 括號生成
22.括號生成 括號問題可以簡單分成兩類,一類是前文寫過的 括號的合法性判斷 一類是合法括號的生成。對於括號合法性的判斷,主要是借助 棧 這種資料結構,而對於括號的生成,一般都要利用回溯遞迴的思想。關於回溯演算法,我們前文寫過一篇 回溯演算法套路框架詳解 反響非常好,讀本文前應該讀過那篇文章,這樣你...