题目地址:Longest Valid Parentheses
题目简介:
给定一个只包含'('和')'的字符串,找出最长的包含有效括号的子串的长度。
Example 1:
Input: "(()"
Output: 2
Explanation: The longest valid parentheses substring is "()"
Example 2:
Input: ")()())"
Output: 4
Explanation: The longest valid parentheses substring is "()()"
题目解析:
1、栈的使用
括号的匹配问题,首先想到的是栈的解决方法。在这里只有一种括号,那么右括号是需要考虑的特殊情况。当出现右括号时,如没有相对应的左括号与之对应,那么这个右括号将不计入最长字段中,并将字符串拆分开来。总结以上,有以下几点需要注意:
- 当前的字符为左括号时,不作处理,将当前位置纪录下来,方便求长度使用;
- 当前的字符为右括号时,假如没有对应的最括号与之对应,那么下一个连续的有效括号肯定在这个字符之后。当有与之对应的括号时,同样存在着两种情况。一种是该右括号刚好将左括号匹配完成,那么这个字符串便是一个有效的括号;另一种是有多个左括号,那么便可以找到最靠近这个右括号的左括号的位置,便可以得到当前位置下的最长括号。
C++版:
class Solution {
public:
int longestValidParentheses(string s) {
int res = 0, start = 0;
stack<int> stc;
for (int i = 0; i < s.size(); ++i)
{
if (s[i] == '(') stc.push(i);
else if (s[i] == ')')
{
if (stc.empty())
start = i + 1;
else
{
res = max(res, i - start + 1);
stc.pop();
res = stc.empty() ? max(res, i - start + 1) : max(res, i - stc.top());
}
}
}
return res;
}
};
2、动态规划
C++版
class Solution {
public:
int longestValidParentheses(string s) {
if (s.length() <= 1)
return 0;
int ans = 0;
int dp[s.size()];
memset(dp,0,sizeof(dp));
for (int i = 1; i < s.size(); i++)
{
if (s[i] == ')')
{
if (s[i - 1] == '(')
dp[i] = (i >= 2 ? dp[i - 2] : 0) + 2;
else if (i - dp[i - 1] > 0 && s[i - dp[i - 1] - 1] == '(')
{
dp[i] = dp[i - 1] + ((i - dp[i - 1]) >= 2 ? dp[i - dp[i - 1] - 2] : 0) + 2;
}
ans = max(ans, dp[i]);
}
}
return ans;
}
};