### 題目
給定一個只包含 '(' 和 ')' 的字符串,找出最長的包含有效括號的子串的長度。
示例 1:
輸入: "(()"
輸出: 2
解釋: 最長有效括號子串爲 "()"
示例 2:
輸入: ")()())"
輸出: 4
解釋: 最長有效括號子串爲 "()()"
### 思路
題目說了是子串,所以一定要連續的,比如()(()就的最長合理子串就是2,兩對括號之間被(隔開了.所以說找到一對合理的括號,同時要與它們的前一位進行聯繫。很明顯就需要使用動態規劃,用dp矩陣記錄每個位置的最長合理子串。
申請一個長度爲字符串長度的一維數組dp,其中dp[i]代表的是在字符串中,從下標爲0的字符到下標爲i的字符形成(子串中一定要包含下標爲i的字符)的子串中最長的子串。
再申請一個stack,用來存儲左括號。
dp的轉移方程爲:
dp[i]=dp[pre]+i-st.top()+1 ,其中pre等於st.top()-1.pre小於0時,不用加上dp[pre].
以字符串()()(()()舉例說明:
遍歷 處理
( 壓入stack中,dp[0]=0.
) 遇到右括號,更新dp[1]=0+1-0+1=2,因爲pre=0-1=-1,所以直接加0;
( 直接壓入stack中,dp[2]=0,包含s[2]的情況下,無法形成合理的子串。
) 遇到右括號,更新dp[3]=2+3-2+1=4,因爲pre=2-1=1,dp[1]=2;
( 壓入stack中,dp[4]=0.
( 壓入stack中,dp[5]=0.
) 遇到右括號,更新dp[6]=0+6-5+1=2,因爲pre=5,所以直接加0;
( 壓入stack中,dp[7]=0.
) 遇到右括號,更新dp[8]=2+8-7+1=4,因爲pre=6,所以直接加2;
所以最後得出結果爲4.
### code
class Solution {
public:
int longestValidParentheses(string s) {
int l=s.size();
int res=0;
vector<int>dp(l,0);
stack<int>st;
for(int i=0;i<l;++i)
{
if(s[i]=='(')
{
st.push(i);
}
else
{
if(!st.empty())
{
int pre=st.top()-1;
int len=0;
if(pre>=0)
{
len=dp[pre]+i-st.top()+1;
}
else
{
len=i-st.top()+1;
}
res=max(res,len);
dp[i]=len;
st.pop();
}
}
}
return res;
}
};