LeetCode:32 最长有效括号 动态规划

题目

给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。

示例 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()];
    }
};
发布了171 篇原创文章 · 获赞 7 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44176696/article/details/104503064