32.longest-valid-parentheses

       括号匹配的题目是leetcode一个常见的题型,从easy到hard各种难度都有,其实他可以归在字符串大类之中,既然是字符串题目,不可避免地灵活性就会非常高,同时也增加了解题的难度。

       这道题目的大体意思是这样的:给定一个只有左括号"("和右括号")"的字符串,求合法的字符串有多长,合法的意思是说左括号必须出现在右括号的左边的情况视为合法情况,例如:()(), (()),不合法的情况例如:)(,以前做过一个题目是判断是否合法,那么这道题目实际上是得到一个最长的合法子串,并输出该长度。

       这个题目可以使用栈的方式来进行匹配,通过不断地压栈和弹栈来判断是否匹配,但是这道题如果直接给栈里面压入括号是不合适的,因为我们需要得到的是最大的合法子串的长度,而不是仅仅判断是否合法,所以,这是这道题目的难点所在,为了得到最大长度,我们最好的方式是记录下标,通过下标之间的减法运算达到目的,具体的思路是这样的。

 <1>、首先,压栈的条件有两个,栈为空的时候需要压栈,因为栈为空,说明为起始状态或者前面的完全符合条件,第二,如果不是栈顶对应的字符是‘(’且当年字符是')'这种情况,则需要将当前元素压栈。以上两种情况都是因为无法完成匹配而对当前元素进行压栈。

 <2>、有压栈操作就有弹栈操作,当栈顶元素为'(‘ 且 当前元素为')',则此时应该将栈顶元素弹出,简单理解就是所有得到匹配的元素都要被弹出。

 <3>、有了上述的压栈和弹栈的操作,相应的,我们要进行计数来得到最大的长度,这里如果满足弹栈要求,我们将对应元素弹出,此时,对应的局部最大长度应该是当前元素的下标减去弹栈后栈顶元素的下标,比如:")()",当判断到第三个字符时,栈中已经压入了0,和1,此时,满足弹栈条件,将1弹出,用当前的下标2减去栈顶元素0,得到最大长度是2。

这里要注意,如果弹出栈顶元素之后,栈空了,则此时最大长度是当前元素的下标加1,因为这说明包括该元素在内的之前所有元素都匹配了。

        提示: 这种题目我们将通过压栈和弹栈的方式完成匹配,但其实代码中如果使用stack会增加程序运行的时间长度,而在这种题目中,vector可以很好模拟一个栈的功能,所以,使用vector程序会快一些。

下面是基于上述描述的代码:

class Solution {
public:
    int longestValidParentheses(string s) {
        int res = 0;
        vector<int> strvec;
        for (int i=0; i<s.size(); ++i) {
            if (strvec.size() && s[strvec.back()] == '(' && s[i] == ')') {
                strvec.pop_back();
                if (!strvec.size()) {
                    res = i+1;
                } else {
                    res = max(res, i-strvec.back());
                }
            } else {
                strvec.emplace_back(i);
            }
        }
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_29592167/article/details/83105242