zoukankan      html  css  js  c++  java
  • 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;
        }
  • 相关阅读:
    jQuery之事件even
    jQuery之动画效果show()......animate()
    jQuery之DOM
    css开发经验&错误习惯
    jQuery语法基础&选择器
    3D案例,导航,导航升级版
    css3实践—创建3D立方体
    CSS3弹性盒模型之Flexbox是布局模块box-sizing & box-orient & box-direction & box-ordinal-group
    Linux-ps命令
    Linux->卸载Mysql方法总结
  • 原文地址:https://www.cnblogs.com/mini-coconut/p/9400554.html
Copyright © 2011-2022 走看看