leetcode 32 - 最长有效括号

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

示例 1:

输入: “(()”
输出: 2
解释: 最长有效括号子串为 “()”
示例 2:

输入: “)()())”
输出: 4
解释: 最长有效括号子串为 “()()”

分析:
一种想法是用栈来解决括号匹配问题,这种方法可行,但我更想用DP的方法来解决。
一开始是考虑用dp[i][j] 表示以第i位结尾的子串 有j个左括号未匹配的最长子串长度
这样最后3个样例都超时,因此考虑有没有O(n)的DP解法。
首先要注意,什么样的子串是满足题意的——一定是以右括号结尾的子串,因此对于左括号结尾的子串,它的长度只能为0,然后满足括号匹配的子串一定会有一个性质——去掉第一个左括号和结尾的右括号,剩下的一定也是一个括号匹配的子串,因此就可以得出第i位结尾的子串的长度一定可以通过第i-1位结尾的子串的长度获得,那么在计算第i位结尾的子串长度的时候,只需要判断:1.它是否为右括号 2.除去它之前的匹配的子串后,往左数第一个括号是否为左括号
如果满足这两个条件,就可以初步得出dp[i] = dp[i-1]+2
但是还没完,这个左括号的左边仍旧有可能有括号匹配的子串,可以知道两个括号匹配的子串串联在一起仍旧是一个括号匹配的字符串,因此在计算完这一步后还要加上dp[i - dp[i] ]

class Solution {
public:
    int longestValidParentheses(string s) {
        int length = s.length();
        vector<int> dp(length+1,0);
        int res = 0;
        for(int i = 2 ; i <= length ; i ++ )
        {
            if(s[i-1] == ')')
            {
                if(s[i - dp[i - 1] - 2 ] == '(')
                {
                    dp[i] = dp[i-1] + 2;
                    dp[i] += dp[i-dp[i]];
                }
                if(res < dp[i]) res = dp[i];
            }
        }
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/yjr3426619/article/details/81012656