题目
给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。
示例 1:
输入: “(()”
输出: 2
解释: 最长有效括号子串为 “()”
示例 2:
输入: “)()())”
输出: 4
解释: 最长有效括号子串为 “()()”
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-valid-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
【用栈的做法】
状态定义:
dp[i]
表示以i
下标结尾的最长有效括号串的长度
状态转移:
如果遇到左括号 '('
,说明以这个左括号结尾的有效括号串长度为0,即没有有效括号串
如果遇到右括号,右括号下标为i
,检查【以i-1
下标结尾的有效括号串】之前的括号,看看是否为 '('
,如果是,那么它和这个右括号 ')'
可以配对,dp[i] = dp[i-1] + 2
例:
0 1 2 3
( ( ) )
已知下标2结尾的最长有效括号长度是 dp[2] = 2;
读到下标3,发现右括号,就要检查下标0是不是左括号
如果是,那么有效的括号延展了!dp[3] = dp[2] + 2;
除此之外,在我们完成上面 ↑ 的一次配对后,还要检查新的有效括号前面是否跟上了另一个有效括号串【 比如下示例中的 “()”,下标为 0和1 的子串】如果在新的串之前存在已有的合法串,把已有的串长度也加进来
检查前面串的时候,记得关注下标是否越界,如果越界了,就不加(因为在计算上一个有效长度的时候,已经加过了,而这一次的结果取决于上一次)
0 1 2 3 4 5
( ) ( ( ) )
代码
class Solution {
public:
int longestValidParentheses(string s)
{
vector<int> dp(s.size()+1);
dp[0] = 0;
for(int i=1; i<s.length(); i++)
{
// 看前面有无 ( 可以配对
if(s[i]==')' && i-dp[i-1]-1>=0 && s[i-dp[i-1]-1]=='(')
dp[i] = dp[i-1]+2;
else
dp[i] = 0;
// 处理连续的情况:()() 要考虑前面是否有合法串,若有,加上
if(dp[i]>0 && i-dp[i]>=0 && dp[i-dp[i]]>0)
dp[i] += dp[i-dp[i]];
}
// 在所有结尾中找最大的长度
return dp[max_element(dp.begin(), dp.end())-dp.begin()];
}
};