LeetCode 最長有效括號

2021-10-09 14:59:44 字數 3073 閱讀 5053

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

示例 1:

輸入: 「(()」

輸出: 2

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

示例 2:

輸入: 「)()())」

輸出: 4

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

思路

1、棧用來儲存讀取到的括號的下標,而不是括號字元。初始時為了統一現在棧底將-1入棧,以便第乙個遇到右括號與之後遇到的情況保持統一的處理

2、保持棧底元素為最後乙個沒有被匹配的右括號下標(初始是-1,一但-1出棧,之後棧底就是儲存最後的未被匹配的有括號下標),這將用來通過讀取的匹配到的右括號的下標來減去此值以獲取當前長度。

3、使用for迴圈,依次獲取字串(括號),如果是左括號』(』,將其下標入棧。

4、如果是右括號』)』,先彈出棧頂元素表示此右括號被匹配了(當然也不一定是匹配了,如果棧中乙個左括號的下標都沒有,那麼其之前要麼有個-1要麼有上乙個未被匹配的右括號的下標在棧中,此時將pop出-1或者上乙個未被匹配的右括號下標並非表示匹配而是表示更新最後乙個未被匹配的右括號下標),然後再接著根據情況判斷

- 如果pop後棧為空,這是因為讀取到右括號時,棧中乙個左括號的下標都沒有,那麼此時棧只有兩種情況,要麼是初始時放入的-1,要麼是上乙個沒有被匹配的右括號下標。所以pop出來後,棧就會進入為空的狀態。而此時,也會將該右括號的下標入棧,更新為最後乙個沒有匹配的右括號。

- 如果pop後不為空,那麼pop出來的必定乙個左括號的下標,那其用於和此時讀取的右括號進行匹配了。此時就可用該右括號的下標減去pop後的棧頂元素(那要麼是-1,要麼是上乙個未被匹配的右括號下標),就可以得到當前有效括號長度。並再用其和之前儲存的最大的有效長度值比較來更新新的最大有效長度

**

// 最長有效括號(求其長度)

public

class

longestvalidparentheses

}return maxlen;

}}

複雜度分析

時間複雜度:o(n),n 是給定字串的長度。我們只需要遍歷字串一次即可。

空間複雜度:o(n)。棧的大小在最壞情況下會達到 n,因此空間複雜度為o(n))。

思路

動態規劃求解需要明確兩點,1.需要記錄的狀態是神什麼。2.如何從這乙個狀態轉移到下乙個狀態(狀態轉移方程)

1、初始化乙個全零的dp陣列,其中的每一位元素用於記錄以該位元素結尾的最長有效子字串的長度

2、很明顯,有效的子字串一定是成對出現的,所以結尾的那個字元一定是右括號。因此我們遇到左括號那dp陣列上的值保持為0,遇到右括號才對dp的值進行重新計算

3、有效字串必定從長度為2開始,因此我們可以在遍歷的時候從i=1開始,碰到』)'右括號時,狀態轉移方程為dp[i−1]+dp[i−dp[i−1]−2]+2。

4、判斷dp[i−dp[i−1]−1]是不是左括號

**

public

intlongestvalidparentheses

(string s)

return maxlen;

}

複雜度分析

間複雜度: o(n),其中 n為字串的長度。我們只需遍歷整個字串一次,即可將 dp陣列求出來。

空間複雜度:o(n),我們需要乙個大小為 n的dp 陣列。

思路

1、分別從左和右遍歷兩次字串

2、每次遍歷用兩個變數left,right記錄遇到的左括號』(『和右括號』)'數量,用len記錄當前有效長度。

3、每當left和right相等時我們記錄一次此時的有效長度,並由此更新當前最長的有效長度。

4、分別從左和從右遍歷是為了搜尋到所有的情況,假如只從左往右,那麼如果一旦出現左括號一直大於右括號則一直無法進入到計算當前有效字串長度,哪怕有有效字串出現,例:……(()()()。所以再來一次反方向就可以考慮到所有的情況了。

5、以從左遍歷為例,當右括號大於左括號數量時,之前的字元便不在考慮了,需要從下乙個字元重新開始統計left和right。若是從右往左就是反過來當left>right時開始重新計算

**

public

intlongestvalidparentheses

(string s)

// 如果只從一邊遍歷,那麼會丟失一種情況

// 如上如果只從左遍歷,那麼一旦出現左括號一直大於右括號就無法更新當前的最大有效長度

// 此時maxlen要麼保持0,要麼一直保持上一次的最大有效長度

// 所以再來一次從右往左遍歷就可以保證所有情況都考慮到了

left = right =0;

for(

int i = s.

length()

-1; i >=

0; i--

)return maxlen;

}

複雜度分析

時間複雜度: o(n),其中 n為字串長度。我們只要正反遍歷兩邊字串即可。

空間複雜度: o(1),我們只需要常數空間存放若干變數。

思路

1、因為要計算的是有效括號長度,而有效括號是成對出現的,最長有效括號一定是偶數

2、加入輸入的乙個字串為長度為12,那麼我們就從12,10,8……每次減2的長度來遍歷。如果奇數就從最大的偶數長度開始

3、每次遍歷依次尋找該遍歷下的所有此長度的子串,只要滿足,那必是最大的,更小的就不再遍歷了

4、有效括號如何判斷之前有一題就是求這個

複雜度分析

時間複雜度:o(n^3) 從長度為n的字串產生所有可能的子字串需要時間複雜度o(n^2),然後驗證乙個長度為n的子字串需要時間複雜度o(n),兩個是巢狀關係所以複雜度相乘

空間複雜度:o(n),子字串的長度最多會需要乙個深度為n的棧

LeetCode 最長有效括號

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

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