20230209 卡一下还是过了
20230218 dp记得初始化
20230220 顺利通过
20230308 顺利通过
原题解

题目

给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。

约束

解法

解法一


class Solution {
public:
    int longestValidParentheses(string s) {
        int maxans = 0, n = s.length();
        vector<int> dp(n, 0);
        for (int i = 1; i < n; 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 - 1]前面已经形成的有效括号长度
                    //i+1才是长度,单独的i是下标,下标=长度-1;长度=下标+1,dp[]对应长度,没有[]的都是下标
                    //i+1-dp[i-1]-1(一个从i-1开始的完整括号对中的左边一个元素)=i - dp[i - 1]>0是因为只看')'结尾保证下标从1也就是第二个元素开始
                    //i+1-dp[i-1]-2(一个完整的括号对之外的左边第一个元素)=i - dp[i - 1] - 1寻找与当前的右括号相匹配的左括号位置
                    //i+1-dp[i-1]-3 = i - dp[i - 1] - 2 '))'对应整体有效括号长度再往前一个位置
                    dp[i] = dp[i - 1] + 2 + ((i - dp[i - 1]) >= 2 ? dp[i - dp[i - 1] - 2] : 0);// 可以与当前的右括号闭合,有效长度增加2
                    // 【注意】此时,需要再往前看下,是否还有有效长度,如果有,合并过来
                    // 例如:"()(()())" 当前在计算最后一个位置时,dp[7]已经等于 dp[6]+2 = 4+2
                    // 但需要再往前看一眼,dp[1]还有有效长度,合并过来 dp[7] = 4+2+2
                    // 那是否还需要再往前看?
                    // 不需要了,因为,如果前面还有有效长度,其长度肯定已经合并到dp[2]上了
                    // 因此,每次只需要再往前多看一眼就可以 ((i - dp[i - 1]) >= 2 ? dp[i - dp[i - 1] - 2] : 0) 
                }
                maxans = max(maxans, dp[i]);
            }
        }
        return maxans;
    }
};

解法二


class Solution {
public:
    int longestValidParentheses(string s) {
        int maxans = 0;
        stack<int> stk;
        stk.push(-1);
        for (int i = 0; i < s.length(); i++) {
            if (s[i] == '(') {
                stk.push(i);
            } else {
                stk.pop();
                if (stk.empty()) {
                    stk.push(i);
                } else {
                    maxans = max(maxans, i - stk.top());
                }
            }
        }
        return maxans;
    }
};

解法三


class Solution {
public:
    int longestValidParentheses(string s) {
        int left = 0, right = 0, maxlength = 0;
        for (int i = 0; i < s.length(); i++) {
            if (s[i] == '(') {
                left++;
            } else {
                right++;
            }
            if (left == right) {
                maxlength = max(maxlength, 2 * right);
            } else if (right > left) {
                left = right = 0;
            }
        }
        left = right = 0;
        for (int i = (int)s.length() - 1; i >= 0; i--) {
            if (s[i] == '(') {
                left++;
            } else {
                right++;
            }
            if (left == right) {
                maxlength = max(maxlength, 2 * left);
            } else if (left > right) {
                left = right = 0;
            }
        }
        return maxlength;
    }
};
posted on 2023-02-05 21:48  垂序葎草  阅读(35)  评论(0编辑  收藏  举报