LeetCode 32 最長有效括號

2021-10-12 16:27:13 字數 3159 閱讀 8483

給定乙個只包含 '(' 和 ')' 的字串,找出最長的包含有效括號的子串的長度。

示例 1:

輸入: "(()"

輸出: 2

解釋: 最長有效括號子串為 "()"

示例 2:

輸入: ")()())"

輸出: 4

解釋: 最長有效括號子串為 "()()"

定義 dp[i] 表示以下標 i 字元結尾的最長有效括號的長度。

1.當s[i-1]=='(' && s[i]==')'時,即字串形如"...()"時

dp[i]=dp[i-2]+2

2.當s[i-1]==')' && s[i]==')'時,即字串形如"...))"時

(這個情況很複雜,詳細分析)

2.1觀察這個括號串0

1234

567(

((()

)))我們希望計算 dp[7] 的值

已知1~6是有效的括號串,所以 -- 條件1: dp[6]==6;  條件2:  s[7 - 6 - 1] 即 s[0] == '('

所以  dp[7] = dp[6] + 2 = 8

所以

if( s[i - dp[i-1] - 1] == '(' )
012

3456

7)((

()))

)已知1~6是有效的括號串,所以 -- 條件1: dp[6]==6;  條件2:  s[7 - 6 - 1] 即 s[0] == ')'

因為條件2 s[0] = ')' ; 所以  dp[7] = 0

然而實際上沒有這麼簡單!!! 在情況2.1的基礎上,還有一種高階情況!!

2.2觀察這個括號串0

1234

5678

91011(

((()

)))(

())我們希望計算 dp[11] 的值

按照前文的情況2.1, 

條件1: dp[10]==6;  條件2:  s[11 - 2 - 1] 即 s[8] == '('

所以 dp[11] =  dp[10] + 2 = 4

上面這個"遞推結果"是錯誤的

為什麼?

我發現,

dp[10]對應 "9~10這2個格仔"

dp[11]在dp[10]的基礎上,向左右兩邊都拓展了一格, 即"8~11這4個格仔"

向左拓展一格對應於 情況2.1 中的這個判斷:

s[i - dp[i-1] - 1] == '('

向右拓展一格對應於

s[i] = ')' 即我們正在求解的這一格

由於向左拓展了一格, 8號格仔和前面的7號格仔相連起來了~~~~

所以,我還需要把 dp[7] 計算在內

假如,7號格仔是"某一有效括號串的結尾字元"

dp[11] =  dp[10] + 2 + dp[7]

假如,7號格仔不是"某一有效括號串的結尾字元"

dp[11] =  dp[10] + 2 + 0

可以寫出如下偽**

if( dp[i - dp[i - 1] - 2] > 0 )

if( dp[i - dp[i - 1] - 2] == 0 )

//精簡後實際上只需要一行

為什麼要畫遞迴樹?因為所謂"遞迴樹"就是一種自頂向下分析問題的思路圖

動態規劃就是自頂向下分析,自底向上求解,所以做動態規劃一定要畫出遞迴樹

就算已經推導出了狀態轉移方程,仍然需要畫出遞迴樹排查有無思維漏洞!!!!!

遞迴樹可以很直觀地看出動態規劃的重疊子問題

有效的括號串一定以 ')' 結尾

所以 '(' 字元結尾的括號串有效長度移動為0,即

if(s.charat(i)=='(')
我設定的邊界條件出錯了,實話說我不知道錯在哪

public class solution 

public int longestvalidparentheses(string s)

//遞迴樹的"....))"分支

else if(s.charat(i-1)==')'&&s.charat(i)==')')}}

}maxans = math.max(maxans, dp[i]);

}return maxans;

}public static void main(string args)

}

實際編碼的時候和思路的時候不一樣

解題思維分幾個過程

1.紙上演算法推演

2.書寫偽**

3.實際編碼

1.紙上演算法推演時,只是形成"人類可讀"的演算法思路

2.書寫偽** 已經開始關注"如何用**表述演算法"但是對於"陣列越界,指標越界等"仍然缺乏**

3.實際編碼要考慮到一切,比如陣列越界等

dp[i] = dp[i - 1] + ((i - dp[i - 1]) >= 2 ? dp[i - dp[i - 1] - 2] : 0) + 2;

//加上"三元算符"是為了防止i - dp[i - 1] - 2處位於陣列頭部,防止陣列從起始處越界

class solution 

//遞迴樹的"....))"分支

else if(s.charat(i-1)==')'&&s.charat(i)==')')}}

}maxans = math.max(maxans, dp[i]);

}return maxans;}}

LeetCode 32 最長有效括號

思路 自己沒想出來,參考了一下網上大神的提示。使用乙個int棧,將左括號記為 1,右括號記為 2 遍歷字串。1.若為 則直接壓入棧 2.若為 分情況討論 若棧頂為 2 或棧空,則直接將 2壓入棧 若棧容量為1,且棧頂為 1,將 1推出棧,推入2,代表此時有一對匹配括號 若棧容量為1,且棧頂大於0,說...

leetcode 32 最長有效括號

一 先對字串進行遍歷 首先從前往後排除不配對的 首次遍歷後的字串被分成若干個字串 再對這些字串 從後往前排除不配對的 int longestvalidparentheses std string s else if s j else t1 j 1 n 0 continue if max2 n max...

LeetCode32 最長有效括號

題目鏈結 500 800ms class solution else if s j for int i 0 ilength i if s i 0 result 0 if result k return result else return k 這絕不是最優解 幾十毫秒之內解決問題 class sol...