最长有效括号

题目描述

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

示例 1:

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

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-valid-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路一(动态规划)

用dp数组记录以当前字符为尾的最长有效括号,显然只有在当前字符是右括号)时才有可能有有效子串,所以分两种情况:
1.当前字符s[i]是右括号),且前一个符号是左括号(。这种情况字符串是这样的“…()”,所以dp[i]=dp[i−2]+2,即前面最长连续有效括号加现在的两个。
2.当前字符s[i]是右括号),且前一个符号也是右括号)。这种情况字符串是这样的“…))”,这时要判断以前一个右括号为尾的最长有效括号之前的一个字符是否是左括号(,如果是左括号,即“…((…))”,则dp[i]应该等于它和它对应左括号中间的有效括号数dp[i−1]加现在的两个,再加对应左括号之前的最长有效括号数dp[i−dp[i−1]−2],即dp[i]=dp[i−1]+dp[i−dp[i−1]−2]+2;如果是右括号,即“…)(…))”,则dp[i]是0.

代码(c++)

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

思路二(栈)

创建一个栈用来存放左括号在字符串中的下标,每当遇到右括号,则栈顶元素出栈,再用右括号的下标减此时栈顶元素的下标作为到现在为止最长有效括号数。当栈顶元素出栈后栈为空时,则直接将右括号下标入栈。一开始将-1入栈,确保栈中始终至少有一个元素。

代码(c++)

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

思路三

顺序遍历字符串,用left和right记录此时左括号和右括号的累计数。当left>right,则继续累加遍历,寻找更多右括号使左括号匹配;如果left

代码(c++)

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

你可能感兴趣的:(LeetCode)