LeetCode 32最长有效括号(困难)
維護不易,還請點個贊贊,如果想加入還請關注公眾號bigsai回復進群加入打卡。
題目描述
給定一個只包含 ‘(’ 和 ‘)’ 的字符串,找出最長的包含有效括號的子串的長度。
示例 1:
輸入: “(()”
輸出: 2
解釋: 最長有效括號子串為 “()”
示例 2:
輸入: “)()())”
輸出: 4
解釋: 最長有效括號子串為 “()()”
分析
再看這題之前,咱們回顧一下前面刷過的題。力扣20有效的括號
分析
這種題核心思想就是使用棧模擬。本題的話更簡單一點因為只有(和 )兩種括號,只有兩個東西的話很多時候可以省略很多內容。在使用暴力的時候就可以循環每次找到最長的有效括號。而括號匹配的時候可以直接終止的情況是當前多個)右括號。例如())(到第三個不可能和前面相連,而如果來(只需要期待后面能夠來)。一個)可以和一個(組成一對,消除棧中的一個(。
當然,在具體的實現上,我們用數組模擬棧,實現代碼為:
public int longestValidParentheses(String s) {char str[]=s.toCharArray();//字符數組int max=0;for(int i=0;i<str.length-1;i++){int index=-1;if(max>=str.length-i)break;for(int j=i;j<str.length;j++){if(str[j]=='(')index++;else {if(index<0){i=j;break;}else {index--;}}if(index==-1&&(j-i+1>max)){max=j-i+1;}}} return max;}盡管有一些地方有優化空間,比如剪枝把各種不可能的給剪掉,但整個算法還是太復雜,算法的復雜度為O(n2).并且只擊敗5%的人,所以在這方面宣告算法宣告失敗:
其實這個暴力是昨晚睡覺前過的, 因為我看到困難級別我在刷的時候用暴力過了好歹我也是過了,過了之后上床之后我就在想怎么去優化這道題。
在今天早上的時候用筆畫了畫想了想成功攻破該題(看不懂不要緊,下面給你慢慢講):
如何將這道題從一個O(n2)的時間復雜度優化到O(n)?很容易, 我們需要注意他的過程。我們先隨便看幾個可能的最大情況。
- ( ) ) ( ) ( ( ) ( ) ) 最大為后面部分
- ( ) ( ) ( ( ( ) 最大為前面部分
- ( ( ( ( ( ( ) ( ) ( ) ( ) 最大為后面部分
對于這么一次獲取你會發現不同括號會有些區別:
(:左括號一旦出現那么他就期待一個)進行匹配,但它的后面可能有)并且在這中間有很多其他括號對。
):右擴號有兩種情況:
- 一種是當前已經超過左括號前面已經不可能連續了。例如( ) ) ( )第三個括號出現已經使得整個串串不可能連續,最大要么在其左面,要么再其右面。 你可以理解其為一種清零初始機制。
- 另一種情況)就是目標棧中存在(可與其進行匹配。匹配之后要疊加到消除后平級的數量上,并且判斷是否是最大值。(下面會解釋)
在具體實現的思路上,就是使用一個int數組標記當前層級(棧深)有正確的括號數量。 模擬一次棧行為從左向右,遇到)太多(當前棧中不存在(進行匹配)就將數據清零重新開始。這樣一直到最后。你可以把它看成臺接,遇到(就上一個臺階并清零該新臺階,遇到)就下一個臺階并且把數量加到下降后的臺階上。具體可以看下面圖片模擬呃過程:
( ) ( ( ) ( ) ( ( ) ) )
仔細看看這張圖,具體實現代碼為:
public static int longestValidParentheses(String s) {int max=0; int value[]=new int[s.length()+1];int index=0;for(int i=0;i<s.length();i++){if(s.charAt(i)=='('){index++;value[index]=0;}else {//")"if(index==0){value[0]=0;}else {value[index-1]+=value[index--]+2;//疊加if(value[index]>max)//更新max=value[index];}}}return max;}
好啦,這個O(n)的復雜度還行,至于其他解法也沒研究有空可以看看。這次打卡就結束啦,如果有興趣的歡迎關注公眾號bigsai 回復進群,加入打卡!一起刷題。
總結
以上是生活随笔為你收集整理的LeetCode 32最长有效括号(困难)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringBoot整合MongoDB(
- 下一篇: LeetCode (二分小专题)33搜索