C 實現LeetCode 32 最長有效括號

2022-09-24 22:27:10 字數 2020 閱讀 7888

given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.

example 1程式設計客棧:

input: "(()"

output: 2

explanation: the longest valid parentheses substring is "()"

example 2:

input: ")()())"

output: 4

explanation: the longest valid parentheses substring is "()()"

這道求最長有效括號比之前那道 validwww.cppcns.com parentheses 難度要大一些,這裡還是借助棧來求解,需要定義個 start 變數來記錄合法括號串的起始位置,遍歷字串,如果遇到左括號,則將當前下標壓入棧,如果遇到右括號,如果當前棧為空,則將下乙個座標位置記錄到 start,如果棧不為空,則將棧頂元素取出,此時若棧為空,則更新結果和 i - start + 1 中的較大值,否則更新結果和 i - st.top() 中的較大值,參見**如下:

解法一:

class solution }}

return res;}};

還有一種利用動態規劃 dynamic programming 的解法。這裡使用乙個一維 dp 陣列,其中 dp[i] 表示以 s[i-1] 結尾的最長有效括號長度(注意這裡沒有對應 s[i],是為了避免取 dp[i-1] 時越界從而讓 dp 陣列的長度加了1),s[i-1] 此時必須是有效括號的一部分,那麼只要 dp[i] 為正數的話,說明 s[i-1] 一定是右括號,因為有效括號必須是閉合的。當括號有重合時,比如 "(())",會出現多個右括號相連,此時更新最外邊的右括號的 dp[i] 時是需要前乙個右括號的值 dp[i-1],因為假如 dp[i-1] 為正數,說明此位置往前 dp[i-1] 個字元組成的子串都是合法的子串,需要再看前面乙個位置,假如是左括號,說明在 dp[i-1] 的基礎上又增加了乙個合法的括號,所以長度加上2。但此時還可能出現的情況是,前面的左括號前面還有合法括號,比如 "()(())",此時更新最後面的右括號的時候,知道第二個右括號的 dp 值是2,那麼最後乙個右括號的 dp 值不僅是第二個括號的 dp 值再加2,還可以連到第乙個右括號的 dp 值,整個最長的有效括號長度是6。所以在更新當前右括號的 dp 值時,首先要計算出第乙個右括號的位置,通過 i-3-dp[i-1] 來獲得,由於這裡定義的 dp[i] 對應的是字元 s[i-1],所以需要再加1,變成 j = i-2-dp[i-1],這樣若當前字元 s[wkehmwi-1] 是左括號,或者j小於0(說明沒有對應的左括號),或者 s[j] 是右括號,此時將 dp[i] 重置為0,否則就用 dp[i-1] + 2 + dp[j] 來更新 dp[i]。這裡由於進行了 padding,可能對應關係會比較暈,大家可以自行帶個例子一步一步執行,應該是不難理解的,參見**如下:

解法二:

class solution else

}return res;}};

此題還有一種不用額外空間的解法,使用了兩個變數 left 和 right,分別用來記錄到當前位置時左括號和右括號的出現次數,當遇到左括號時,left 自增1,右括號時 right 自增1。對於最長有效的括號的子串,一定是左括號等於右括號的情況,此時就可以更新結果 res 了,一旦右括號數量超過左括號數量了,說明當前位置不能組成合程式設計客棧法括號子串,left 和 right 重置為0。但是對於這種情況 "(()" 時,在遍歷結束時左右子括號數都不相等,此時沒法更新結果 res,但其實正確答案是2,怎麼處理這種情況呢?答案是再反向遍歷一遍,採取類似的機制,稍有不同的是此時若 left 大於 right 了,則重置0,這樣就可以 cover 所有的情況了,參見**如下:

解法三:

class solution

left = right = 0;

for (int i = n - 1; i >= 0; --i)

return res;}};

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...