[Leetcode] Longest Valid Parentheses 最長有效括號對

Longest Valid Parentheses

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

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

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

棧法 Stack

複雜度

時間 O(N) 空間 O(N)orm

思路

用Stack的方法本質上和Valid Parentheses是同樣的,一個右括號能消去Stack頂上的一個左括號。不一樣的是,爲了可以計算括號對的長度咱們還須要記錄括號們的下標。這樣在彈出一個左括號後,咱們能夠根據當前座標減去棧中上一個(也就是Pop事後的Top元素)的座標來獲得該有效括號對的長度。字符串

代碼

public class Solution {
    public int longestValidParentheses(String s) {
        Stack<Parenthese> stk = new Stack<Parenthese>();
        int maxLen = 0;
        for(int i = 0; i < s.length(); i++){
            //遇到左括號,將其push進棧
            if(s.charAt(i)=='('){
                stk.push(new Parenthese(i, '('));
            } else {
           //遇到右括號,分類討論
               //若是當前棧頂是左括號,則消去並計算長度
                if(!stk.isEmpty() && stk.peek().symb=='('){
                    int curLen = 0;
                    stk.pop();
                    if(stk.isEmpty()){
                        curLen = i + 1;
                    } else {
                        curLen = i - stk.peek().indx;
                    }
                    maxLen = Math.max(maxLen, curLen);
                } else {
               //若是棧頂是右括號或者是空棧,則將右括號也push進棧,它的座標將方便以後計算長度
                    stk.push(new Parenthese(i, ')'));
                }
            }
        }
        return maxLen;
    }
    
    public class Parenthese {
        int indx;
        char symb;
        public Parenthese (int i, char s){
            this.indx = i;
            this.symb = s;
        }
    }
}

動態規劃法 Dynamic Programming

複雜度

時間 O(N) 空間 O(N)get

思路

動態規劃法將大問題化爲小問題,咱們不必定要一會兒計算出整個字符串中最長括號對,咱們能夠先從後向前,一點一點計算。假設d[i]是從下標i開始到字符串結尾最長括號對長度,s[i]是字符串下標爲i的括號。若是s[i-1]是左括號,若是i + d[i] + 1是右括號的話,那d[i-1] = d[i] + 1。若是不是則爲0。若是s[i-1]是右括號,由於不可能有右括號開頭的括號對,因此d[i-1] = 0。string

代碼

public class Solution {
    public int longestValidParentheses(String s) {
        int[] dp = new int[s.length()];
        int maxLen = 0;
        for(int i = s.length()-2; i >=0; i--){
            if(s.charAt(i)=='('){
                int end = i + dp[i+1] + 1;
                if(end < s.length() && s.charAt(end)==')'){
                    dp[i] = dp[i+1] + 2;
                    if(end + 1 < s.length()){
                        dp[i] += dp[end + 1];
                    }
                }
            }
            maxLen = Math.max(maxLen, dp[i]);
        }
        return maxLen;
    }
}

後續 Follow Up

Q:可否不用額外空間求解?
A:能夠,可是要提升時間複雜度。好比((()()),先遍歷一遍將全部的()替換成00,獲得((0000),再遍歷一遍,替換全部的(00...00)這種形式字符串爲000...000,這裏咱們獲得(000000,直到遍歷完沒法替換更多括號爲之。若是全部符號都是0,說明是有效的。這樣的時間複雜度是O(N)。io

相關文章
相關標籤/搜索