leetcode第31题--Longest Valid Parentheses

Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.

For "(()", the longest valid parentheses substring is "()", which has length = 2.

Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4.

给定一串只包含左右括号的字符串,判断里面合法的个数。左右括号镶嵌嵌套也是合法的例如(())(),合法的和合法的相连也是合法的。这个用DP是可以的。在http://www.cnblogs.com/huntfor/p/3886111.html中介绍了DP可以通过。在http://www.cnblogs.com/lichen782/p/leetcode_Longest_Valid_Parentheses.html的DP却说通不过。改天要好好复习一下动态规划。

我学习了如下的解法。就是按照从前往后遍历,遇到左括号就放入栈中,栈是用来存左括号的下标的,方便之后计算长度。遇到右括号的话考虑两种情况,如果此时栈为空,那这个右括号就是违法的,用last记录它的位置,这样last就记录了我们遍历到i为止的最后一个违法的数,这样的话,再往下遍历,如果发现栈为空了的时候就可以用i-last来表示刚才在i和last中间合法的个数。如果往下遍历发现栈不为空,那么就用当前的i-栈顶元素,因为栈顶元素记录的是离i最近的一个左括号,所以i减去它就记录了他们之间合法的个数,如果大于max就更新。就这样一直遍历到i结束为止。最后输出max就是结果了

class Solution {
    public:
    int longestValidParentheses(string s)
    {
        if (s.size() < 2)
            return 0;
        stack<int> sta;
        int last = -1, max = 0;
        
        for (int i = 0; i < s.size(); i++)
        {
            if (s[i] == '(') // 如果是左括号,就将其对应的下标存到栈中
                sta.push(i);
            if (s[i] == ')') // 如果是右括号
            {
                if (sta.empty()) // 如果栈为空,last记录为i,也就是遍历到此i的最后一个不符合的右括号的位置
                {
                    last = i;
                }
                else // 如果不空,那就pop一个左括号的下标
                    sta.pop();
            }
            if (sta.empty()) //如果以上操作,sta为空,那么就记录最后一个右括号到i的个数-1为合法的个数
                max = std::max(max, i - last);
            else // 如果sta还有左括号,那就用剩下的没有匹配的括号到i的个数-1为合法的个数和max比较
                max = std::max(max, i - sta.top());
        }
        return max;
    }
};
原文地址:https://www.cnblogs.com/higerzhang/p/4044671.html