演算法 回溯法(雙路徑回溯 括號生成)

2021-10-23 05:22:45 字數 2153 閱讀 6461

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.括號生成 括號問題可以簡單分成兩類,一類是前文寫過的 括號的合法性判斷 一類是合法括號的生成。對於括號合法性的判斷,主要是借助 棧 這種資料結構,而對於括號的生成,一般都要利用回溯遞迴的思想。關於回溯演算法,我們前文寫過一篇 回溯演算法套路框架詳解 反響非常好,讀本文前應該讀過那篇文章,這樣你...