LC.32. 最長有效括號

LC.32. 最長有效括號

傳送門

挺好的一個題,這裏主要再分析一下官方的解法。

思路:

1.dpdp

令以下標ii結尾的字符串的最大長度爲dp[i]dp[i],顯然s[i]=(s[i]='('dp[i]=0dp[i]=0.

s[i]=)s[i]=')',需要討論兩種情況。

1:1: s[i1]=(s[i-1]='(' ,這樣顯然有dp[i]=dp[i2]+2dp[i]=dp[i-2]+2.

2:s[i1]=)2:s[i-1]=')' ,因爲我們已知dp[i1]dp[i-1],我們可以找到dp[i1]dp[i-1]的開始匹配的前面 一個位置即pos=(i1)dp[i1]pos=(i-1)-dp[i-1],顯然如果s[pos]=)s[pos]=')',是不能更新的,因爲s[pos]s[pos]一定是未被匹配的)')',不然dp[i1]dp[i-1]會包含掉它,所以顯然s[pos]=(s[pos]='(',才能與s[i]=)s[i]=')'進行匹配,然後再加上dp[pos1]dp[pos-1]的長度就可以了。

dp[i]=dp[i1]+2+dp[i2dp[i1]]dp[i]=dp[i-1]+2+dp[i-2-dp[i-1]]

時間複雜度:O(n)O(n)

class Solution {
public:
    int longestValidParentheses(string s) {
        int n=s.length(),ans=0;
        vector<int>dp(n,0);
        for(int i=1;i<n;i++){
            if(s[i]=='(') dp[i]=0;
            else if(s[i-1]=='('){
                 dp[i]=(i>=2?dp[i-2]:0)+2;
            }
            else if(i-dp[i-1]>0&&s[i-1-dp[i-1]]=='(')
                dp[i]=(i-2-dp[i-1]>=0?dp[i-2-dp[i-1]]:0)+2+dp[i-1];
            ans=max(ans,dp[i]);
        }
        return ans;
    }
};

2.棧。

顯然對於這樣的後綴表達式問題,用棧是很方便的。這裏是參考官方大大的解法,預先放一個元素1-1,保證棧底是未被匹配的最後一個右括號下標,如果是左括號直接入棧,否則彈出棧頂元素,如果棧是空的表示不能更新,否則長度爲isk.top()i-sk.top()

時間複雜度:O(n)O(n)

class Solution {
public:
    int longestValidParentheses(string s) {
        int n=s.length(),ans=0;
        stack<int>sk;sk.push(-1);
        for(int i=0;i<n;i++){
            if(s[i]=='(') sk.push(i);
            else {
                sk.pop();
                if(sk.empty()) sk.push(i);
                else ans=max(ans,i-sk.top());
            }
        }
        return ans;
    }
};

3.統計左右括號數。

這種方法我覺得比第二種好理解點,先順序遍歷一遍,如果是左括號l++l++,否則r++r++,左右括號數相等就更新長度,若r>lr>l,則可以捨棄掉前面所有的括號,l=r=0l=r=0

因爲順序遍歷沒有考慮到l>rl始終>r的情況,這樣就更新不了。

所以再逆序遍歷一遍,l>rl>rl=r=0l=r=0.這樣就考慮到所有情況了。

時間複雜度:O(2n)O(2n)

class Solution {
public:
    int longestValidParentheses(string s) {
        int n=s.length(),ans=0;
        int l=0,r=0;
        for(int i=0;i<n;i++){
            if(s[i]=='(') l++;
            else r++;
            if(l==r) ans=max(ans,l*2);
            else if(r>l) l=r=0;
        }
        l=r=0;
        for(int i=n-1;i>=0;i--){
            s[i]=='('?l++:r++;
            if(l==r) ans=max(ans,l*2);
            else if(l>r) l=r=0;
        }
        return ans;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章