LeetCode-32-最长有效括号

LeetCode-32-最长有效括号_第1张图片

1、动态规划法

观察括号字串的特点,我们可以找到如下特点:由于我们需要寻找的是最长有效括号子串,因此该字串的结尾一定是“)”。基于这一特点,我们只需要通过不断增大位数i,当s[i] = “)”时对前i位中的最长有效括号子串的不同情况进行讨论即可:1、当s[i]=“)”且s[i-1]=“(”时,很显然,此时的有效括号子串相当于在第i-2位的最长有效括号子串的基础上+2,因而我们可以得到状态转移方程为:dp[i]=dp[i-2]+2;2、当s[i]=“)”且s[i-1]=“)”时,此时的新字符串可能是一个有效的括号子串,但需要满足如下的条件——即s[i - dp[i - 1] - 1]应等于“(”。我们可以这样考虑,若这是一个有效的括号子串,则显然实在读到第i位时才增加了长度,因而此时dp[i-1]应有一个不为0的值,这个长度的子串一定是一个最长有效括号子串。因此为了证明新读入的s[i]位上的")"能够与之前的“(”构成一对,则i - dp[i - 1] - 1上必须为“(”,否则则不会是一个最长有效括号子串。因此我们可以得到状态转移方程为:dp[i]=dp[i-1]+dp[i-dp[i-1]-2]+2。

在完成状态转移方程之后,我们还需要对特殊情况进行考虑,即i-2和i-dp[i-1]-2可能会导致数组下标越界,处理完特殊情况之后即可实现。

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

你可能感兴趣的:(LeetCode刷题记录,leetcode,动态规划,算法)