Longest Valid Parentheses
Given a string containing just the characters '('
and ')'
, find the length of the longest valid (well-formed) parentheses substring.
For "(()"
, the longest valid parentheses substring is "()"
, which has length = 2.
Another example is ")()())"
, where the longest valid parentheses substring is "()()"
, which has length = 4.
此题初看简单,但是细想并非如此。很容易想到使用栈来做此题(或直接使用int等标记来模拟栈,但终归为栈的思想)。
但是,对于此类的输入:(()((()))
直接数括号的配对最大长度所得的结果为6,也就是结果为最后的三组括号长度。但是明显,前面的一对括号(长度为2)也应该被计算在结果总,因此正确结果应该是8。而且这种情况还存在嵌套、重复等更为复杂的情况,也就是说我们后续的计算需要用到此前计算的结果。
可以理解为一种动态规划:
设f[i]表示恰以s[i]结尾的正确匹配字符串最大值
如果s[i] == '(',则 f[i] = 0; // 一个正确的匹配字符串不可能以'('作为结尾,始终为0
如果s[i] == ')',则 f[i] = 当前匹配的最大长度len + f[i - len]; // i - len就是指与当前使用栈来匹配的字符串紧邻的前面的恰以s[i-len]结尾的正确匹配字符串最大值。
代码如下:
class Solution { // (()(((()
public:
inline static int fast_max(int a, int b) {return a > b ? a : b;}
int longestValidParentheses(string s) {
int max_len = 0;
stack<int> match_stack;
vector<int> dp(s.length(), 0);
for (int i = 0; i < s.length(); i++)
{
if (s[i] == '(')
{
match_stack.push(i);
}
else if (!match_stack.empty())
{
int top = match_stack.top();
match_stack.pop();
dp[i] = i - top + 1;
if (top > 0)
dp[i] += dp[top - 1];
max_len = fast_max(max_len, dp[i]);
}
}
return max_len;
}
};