leetcode 最長有效括號 線性dp,棧

2021-09-29 17:42:35 字數 2187 閱讀 5593

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

示例 1:

輸入: 「(()」

輸出: 2

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

示例 2:

輸入: 「)()())」

輸出: 4

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

有效括號最小有兩種情況:

() 左括號和右括號相鄰。

(()) 左括號和右括號不相鄰。

基於這兩種基本情況設計dp.設dp[i]是以s[i]字元結尾的最長有效括號長度。那麼可以分析出每個』(『對應下標的長度都是0. 對於』)』,按照上面兩種情況來設計方程。

對於第一種情況,若s[i] == 『)』 && s[i-1] == 『(』 那麼dp[i] = dp[i-2]+2.

為什麼這樣設計呢?因為如果s[i-2]是左括號和無效的右括號(多出來的),那麼dp[i]=2毋庸置疑。如果s[i-2]是乙個有效的右括號,那麼最長有效括號長度就是之前的有效括號長度(dp[i-2])加上當前』()'的括號長度2。

對於第二種情況,若s[i] == 『)』 && s[i-1] == 『)』 && s[i-dp[i-1]-1] == 『(』

則dp[i] = dp[i-1] + 2 + dp[i-dp[i-1]-2].

令pre_index = i-dp[i-1]-1 先分析一下pre_index的含義:dp[i-1]表示前面右括號的最長有效括號長度,那麼i-dp[i-1]-1就是指向當前右括號應當匹配的左括號的下標。

舉個例子:)(()) 對於最後的右括號來說,i = 4,dp[i-1] = 2,pre_index = i-dp[i-1]-1 = 1,i=4的右括號所匹配的左括號的位置應當在下標1的位置。於是對這個位置即pre_index判斷:s[pre_index]是右括號,不配對,dp[i] = 0;如果s[pre_index]是左括號,配對成功,dp[i] = dp[i-1]+2. 至於加上的dp[i-dp[i-1]-2],即dp[pre_index-1]的含義其實和第一種情況的dp[i-2]的含義是一樣的,如果s[pre_index-1]也是乙個有效右括號,那麼就要將之前的有效括號長度連起來。比如()(()),對於最後的右括號i = 5, pre_index-1=1,dp[1] = 2,兩個長度連起來,dp[i] = 2+4 = 6.

**如下:

class solution 

else

if(s[i -1]

==')')if

(dp[i]

> longestlen) longestlen = dp[i];}

}return longestlen;}}

;

其實對於這種有效括號的問題,最先想到的應該就是棧。不過題目要求的是最長有效括號,用棧去做的時候發現有一些斷點不知道怎麼處理,看了leetcode題解才發現這種棧的運用之巧妙。

舉乙個例子:()((())和())(()) 乙個是s[2]=』(』 ,乙個是s[2]=』)』. 這個s[2]就是乙個斷點。如果我們按照正常的括號匹配來做,就是遇到左括號進棧,遇到右括號且棧不空,將左括號出棧,這樣就無法處理斷點的問題。

我們可以換個方式運用棧:設棧名為st,將左括號和斷點轉化為下標進棧。先將-1壓進棧作為起點便於計算區間長度。

拿上面的第二個例子說明:

i=0,左括號進棧。

i=1,遇到右括號,左括號出棧,計算長度:i-st.top() = 1-(-1) = 2.

i=2,遇到右括號,-1出棧。這時候棧空了,右括號進棧作為斷點。

i=3,左括號進棧。

i=4,左括號進棧。

i=5,遇到右括號,左括號出棧,計算長度:5-st.top() = 5-3 = 2.

i=6,遇到右括號,左括號出棧,這時候棧中剩下的就是之前進棧的右括號斷點。計算長度:6-st.top() = 6-2 = 4.

因此,我們就可以得到最大的長度為4. 如果棧空了,就表示右括號多出來了,前面和後面不能連起來,因此該右括號下標進棧表示斷點就可以方便計算後面的有效括號長度,然後比較前面和後面取最大就是最長有效括號。

**如下:

class solution 

}return maxans;}}

;

LeetCode 最長有效括號

方法一 方法二 給定乙個只包含 和 的字串,找出最長的包含有效括號的子串的長度。示例 1 輸入 輸出 2 解釋 最長有效括號子串為 示例 2 輸入 輸出 4 解釋 最長有效括號子串為 有效的括號 括號的生成 出棧入棧方法 參考之前的有效括號題目,當 前乙個為 則刪除這對,當全部刪除則為有效括號。在棧...

LeetCode 最長有效括號

給定乙個只包含 和 的字串,找出最長的包含有效括號的子串的長度。示例 1 輸入 輸出 2 解釋 最長有效括號子串為 示例 2 輸入 輸出 4 解釋 最長有效括號子串為 思路 1 棧用來儲存讀取到的括號的下標,而不是括號字元。初始時為了統一現在棧底將 1入棧,以便第乙個遇到右括號與之後遇到的情況保持統...

LeetCode 32 最長有效括號

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