【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; }