leetcode32 Longest Valid Parentheses 最長括號組的長度

題目要求

原題地址:https://leetcode.com/problems...面試

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

For "(()", the longest valid parentheses substring is "()", which has length = 2.

Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4.

一個括號序列,求出其中成對括號的最大長度segmentfault

思路一:使用堆棧

這題能夠參考個人另外一篇博客,這篇博客講解了如何用堆棧判斷括號序列是否能夠成對。咱們能夠將堆棧的思路延續到這裏。每當遇到一個左括號或者是沒法成對的右括號,就將它壓入棧中,能夠成對的括號則從棧中壓出。這樣棧中剩下的就是沒法成對的括號的下標。這時咱們能夠判斷這些下標間的距離來得到最大的成對括號長度。在這裏須要先遍歷一遍字符串,再遍歷一下非空的堆棧。數組

public int longestValidParentheses(String s) {
        Stack<Parenthese> parenthesesStack = new Stack<Parenthese>();
        for(int i = 0 ; i < s.length() ; i++){
            char symbol = s.charAt(i);
            if(symbol==')'){
                //在這裏左右括號能夠成對,則出棧
                if(!parenthesesStack.isEmpty() && parenthesesStack.peek().symbol=='('){
                    parenthesesStack.pop();
                    continue;
                }
            }
            //其餘狀況都壓入棧中
            parenthesesStack.push(new Parenthese(symbol, i));
        }
        int maxLength = 0;
        int nextIndex = s.length();
        while(!parenthesesStack.isEmpty()){
            int curIndex = parenthesesStack.pop().index;
            maxLength = (nextIndex-curIndex-1)>maxLength ? nextIndex-curIndex-1 : maxLength;
            nextIndex = curIndex;
        }
        return Math.max(nextIndex, maxLength);
    }
    
    public class Parenthese{
        char symbol;
        int index;
        public Parenthese(char symbol, int index){
            this.symbol = symbol;
            this.index = index;
        }    
    }

在這裏能夠優化,由於使用數據結構不是必要的。咱們能夠直接壓入棧中下標,再從字符串中得到該下標對應的字符微信

public int longestValidParentheses_noDataStructure(String s) {
        Stack<Integer> parenthesesStack = new Stack<Integer>();
        for(int i = 0 ; i < s.length() ; i++){
            if(s.charAt(i)==')'){
                if(!parenthesesStack.isEmpty() && s.charAt(parenthesesStack.peek())=='('){
                    parenthesesStack.pop();
                    continue;
                }
            }
            parenthesesStack.push(i);
        }
        int maxLength = 0;
        int nextIndex = s.length();
        while(!parenthesesStack.isEmpty()){
            int curIndex = parenthesesStack.pop();
            int curLength = nextIndex-curIndex-1;
            maxLength = curLength>maxLength ? curLength : maxLength;
            nextIndex = curIndex;
        }
        return Math.max(nextIndex, maxLength);
    }

思路二:dynamic programming

dynamic programming 的真 奧義其實在於假設已知以前全部的結果,結合以前的結果窮盡每一種當前值可能的狀況
在這道題目中,咱們假設已經知道長度爲n-1字符串中,到每個下標爲止的的最大的括號組長度,這些值被存儲在和字符串長度等長的int數組s中,其中s的下標表明字符串的下標,s的值表明到這個字符串下標爲止最長括號組長度。
那麼當前第n個符號主要有如下三種狀況:數據結構

  1. 當前值爲‘(’,那麼不管前面狀況如何,當前必定是沒法造成括號的,因此最大長度爲0
  2. 當前值爲‘)’,前一個值爲‘(‘, 那麼最大長度爲s[n-2](若是存在的話)+ 2
  3. 當前值爲‘)’,前一個值也是')',若是在i-s[i-1]-1的位置上是一個’(‘,那麼最大長度爲s[i-1]+2+s[i-s[i-1]-2],具體狀況能夠參考()(())當n=5時,不然仍舊爲0

代碼實現以下優化

public int longestValidParentheses_dynamicProgramming(String s) {
        int[] maxCount = new int[s.length()];
        int maxLength = 0;
        for(int i = 1 ; i<s.length() ; i++){
            if(s.charAt(i) == ')'){
                if(s.charAt(i-1)=='('){
                    maxCount[i] = (i>=2? maxCount[i-2]+2 : 2);
                    maxLength = Math.max(maxCount[i], maxLength);
                }else{
                    if(i-maxCount[i-1]-1>=0 && s.charAt(i-maxCount[i-1]-1)=='('){
                        maxCount[i] = maxCount[i-1]+2 + ((i-maxCount[i-1]-2 >= 0)?maxCount[i-maxCount[i-1]-2]:0);;
                        maxLength = Math.max(maxCount[i], maxLength);
                    }
                }
            }
        }
        return maxLength;        
    }

簡化後的代碼以下:this

public int longestValidParentheses_dynamicProgrammingConcise(String s) {
        int[] maxCount = new int[s.length()];
        int maxLength = 0;
        for(int i = 1 ; i<s.length() ; i++){
            if(s.charAt(i) == ')' && i-maxCount[i-1]-1>=0 && s.charAt(i-maxCount[i-1]-1)=='('){
                maxCount[i] = maxCount[i-1] + 2 + ((i-maxCount[i-1]-2>=0) ? maxCount[i-maxCount[i-1]-2] : 0);
                maxLength = Math.max(maxCount[i], maxLength);
                
            }
        }
        return maxLength;        
    }

clipboard.png
想要了解更多開發技術,面試教程以及互聯網公司內推,歡迎關注個人微信公衆號!將會不按期的發放福利哦~spa

相關文章
相關標籤/搜索