Leetcode(32)-最长有效括号

Posted Mini_Coconut

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode(32)-最长有效括号相关的知识,希望对你有一定的参考价值。

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

示例 1:

输入: "(()"
输出: 2
解释: 最长有效括号子串为 "()"

示例 2:

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

思路:这个题目和前面一个有效括号很类似,不过那个是判断整个字符串是否是合法的括号,这个要从字符串中找到最长的有效字符串。还可以用栈来实现,也可以想到动态规划,不过个人觉得动态规划的方法比较难以理解。

用栈来实现,我一开始的实现方式是:遇到左括号就压栈,遇到右括号,则要判断栈顶是否是左括号来匹配,如果是的话,将栈顶出栈,配成一组合法的括号,但是这里应该注意,这里不能直接在最后结果上加上长度2。因为像这种情况“(()(”,虽然中间第二个和第三个可以匹配成一个合法括号,但是最后一个和第一个并没有匹配成功,所以前面的那个并不能算入结果中。我们可以想到,当我将栈顶出栈之后,如果栈为空了,证明我这个目前的字符串一定是合法的,而且是可计入结果的。

所以要先暂时存起来一个结果,栈为空时,才能计入最终的最长有效的长度中。

最后从第一个字符开始暴力求解,求以每个字符串为首的最长有效括号的长度,最后得到最大的一个长度。

int isValid(string s)
{
    stack<int> sta;
    int num=0;
    int t=0;
    for(int i=0;i<s.size();i++)
    {
        if(s[i]==( )
            sta.push(s[i]);
        else if(sta.empty())
        {
            return num;
        }
        else if(s[i]==) && !sta.empty())
        {
            sta.pop();
            t+=2;
            if(sta.empty())
            {
                num+=t;
                t=0;
            }
        }
        else
        {
            return num;
        }
    }
    return num;
}
int longestValidParentheses(string s) 
{
    int len=s.size();
    if(len==0 || len==1) return 0;
    int maxlen=0;
    for(int i=0;i<len;i++)
    {
        maxlen=max(maxlen,isValid(s.substr(i,len)));
    }
    return maxlen;
}

上述的解法时间复杂度肯定是高的,因为它要从每个字符开始求解来找到最大值。

我们其实直接将字符的下标压栈,这样就可以通过下标的减法就可以得到字符串的长度了。从头遍历,当前字符为左括号时,压栈,当前字符为右括号时,分为栈中为空(重新选当前字符下一个为起始点),栈中为1(长度为j-i+1),栈中个数大于1(接着匹配,看以后是否还有合法的括号)

int longestValidParentheses(string s) {
        int ans = 0;
        stack<int> stk;
        for (int i = 0, j = 0; j < s.size(); j++) {
            if (s[j] == () {
                stk.push(j);
            } else {
                if (stk.size() > 1) {
                    stk.pop();
                    ans = max(ans, j - stk.top());
                } else if (stk.size() == 1) {
                    stk.pop();
                    ans = max(ans, j - i + 1);
                } else {
                    i = j + 1;//i用来表示起始点
                }
            }
        }
        return ans;
    }

 

以上是关于Leetcode(32)-最长有效括号的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 32. 最长有效括号c++/java详细题解

[Leetcode] 32.最长有效括号

leetcode 32: 最长有效括号

leetcode32 最长有效括号(Hard)

Leetcode(32)-最长有效括号

Leetcode_32最长有效括号