【Leetcode] 32最長有効ブラケット

【Leetcode] 32最長有効ブラケット

キーワード:DP、動的プログラミング、動的ルール。

質問の中で、最近のブラシDP欄トピック、で。

のみを含むことを考慮する'('')'、文字列、最長のサブ文字列を検索することが効果的な括弧を備えます。

最長有効-括弧

サンプル1

输入: "(()"
输出: 2
解释: 最长有效括号子串为 "()"

サンプル2

输入: ")()())"
输出: 4
解释: 最长有效括号子串为 "()()"

DPさて、上記のすべて、抽象状態の機能に必要な場合:

dp[i] 表示:以 S[i] 结尾的,最长有效括号串的长度。

そして、状態遷移方程式:

如果 s.len == 0 or s.len == 1,那么返回 0 .
否则:
    if s[i]=='(' then dp[i]=0
    if s[i]==')' then:
        if s[i-1]='(' then dp[i] = dp[i-2] + 2 (数组下标是否越界,即 i>=2? )
        if s[i-1]=')' then:
            if s[i-dp[i-1]-1] == '(' then dp[i] = dp[i-dp[i-1]-2] + dp[i-1] + 2 (是否越界?)
            if s[i-dp[i-1]-1] == ')' then dp[i] = 0

最初ifの形式:ステートメントがあることを示し....(、このような文字列のは、必ずしも有効ではありません。

第二ifのような形:声明は述べ....)、このような文字列を、私たちは考慮する必要がありますs[i-1]

  • s[i-1]='(':文字列のような形状の...()、明らかに、次のインデックスに対応します。

    i-2   i-1    i
     x     (     )       

    明らかに、dp[i]値がでなければなりませんdp[i-2] + 2

  • s[i-1]='):文字列のような形状の...))、明らかに、次のインデックスに対応します。

    ?          i-1    i
    x   (...    )     )

    今考えるs[i-1]一致する左括弧の位置s[i-1]=')'正当な括弧の文字列の長さであるがdp[i-1]'('位置は次のようになります。

    i - 1 - (dp[i-1] - 1) = i - dp[i-1]

    換言すれば、s[i] = )マッチング左括弧の位置は次のようになりますi - dp[i-1] - 1

    i-dp[i-1]-1  i-dp[i-1]        i-1    i
        x            (      ...    )     )

    もしx = s[i-dp[i-1]-1] == )、その後、: dp[i] = dp[i-dp[i-1]-2] + dp[i-1] + 2まだ括弧文字列に有効である前に「私は引き出していなかった」ので)

    しかし場合はi-dp[i-1]-1、この位置のシンボルではありません(、それ?これは、とすることを示しているs[i]パスの末尾に括弧つまり、正当ではないですd[i] = 0

    完全なコード:

    問題の範囲外の特別な注意配列添字を必要とし、境界たら、上記の説明は、有効な文字列のブラケットではありません。

    /*
        DP解法:
        dp[i] 表示:以s[i]结尾的,最长有效子串
        那么:
            if s[i]=='(' then dp[i] = 0
            if s[i]==')':
                if (s[i-1]=='(') then dp[i] = dp[i-2]+2
                if (s[i-1]==')') then dp[i] = dp[i-dp[i-1]-2] + dp[i-1] + 2
    
     */
    #include "leetcode.h"
    #include <stack>
    class Solution
    {
    public:
        int longestValidParentheses(string s)
        {
            int len = s.length();
            if (len == 0 || len == 1)
                return 0;
            vector<int> dp(len, 0);
            for (int i = 1; i < len; i++)
            {
                if (s[i] == ')')
                {
                    if (s[i - 1] == '(')
                    {
                        if (i >= 2)
                            dp[i] = dp[i - 2] + 2;
                        else
                            dp[i] = 2;
                    }
                    else if (s[i - 1] == ')')
                    {
                        int midlen = dp[i - 1];
                        if (i >= (midlen + 1))
                        {
                            char c = s[i - midlen - 1];
                            if (c == '(')
                                dp[i] = dp[i - 1] + 2 + (i >= (midlen + 2) ? dp[i - midlen - 2] : 0);
                            else
                                dp[i] = 0;
                        }
                        else
                        {
                            dp[i] = 0;
                        }
    
                    }
                }
            }
            for (int x : dp)
                cout << x << ' ';
            cout << endl;
            int result = -1;
            for (int x : dp)
                result = max(result, x);
            return result;
        }
    };
    
    int main()
    {
        string s[] = {"())", "(()", ")()())"};
        Solution sol;
        for (int i = 0; i < 3; i++)
            cout << sol.longestValidParentheses(s[i]) << "\n"
                 << endl;
    }

おすすめ

転載: www.cnblogs.com/sinkinben/p/11516742.html