leetcode 32. 最长有效括号

32. 最长有效括号

问题描述

给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。
示例 1:
输入: "(()"
输出: 2
解释: 最长有效括号子串为 "()"
示例 2:
输入: ")()())"
输出: 4
解释: 最长有效括号子串为 "()()"

问题分析

我们从左到右进行扫描,我们使用栈lefts来存放左括号,有两种情况:

  • 1.遇到'(',直接入栈;
  • 2.遇到')',需要检查之前左括号的情况:
    • 2.1 如果lefts空了,说明没有左括号与目前的右括号匹配,我们记录下当前右括号的位置last;
    • 2.2 如果lefts不空,说明可以找到左括号与目前右括号匹配,我们把这个左括号出栈,这时还要分两种情况讨论:
      • 2.2.1 如果lefts空了,说明左括号已经匹配完了,我们需要更新最大长度,这时初始位置和之前的last有关(i - last);
      • 2.2.2 如果lefts不空,说明还有剩下的左括号没有被匹配,我们同样需要更新最大长度,这时初始位置和最顶上的左括号有关(i - lefts.top());

当然也可以把2.2.1和2.2.2理解为一个位置,那就是被匹配的左括号之前的一个位置,但是如果栈空了就没法找到这个位置,因此我们使用一个last来进行记录。

代码

class Solution {
public:
    int longestValidParentheses(string s) {
        int n = s.size();
        if(n < 2) return 0;
        stack<int> lefts;
        int i,ans = 0,last = -1;
        for(i = 0; i < n; i++)
        {
            if(s[i] == '(')
                lefts.push(i);
            else{
                if(!lefts.empty())
                {
                    lefts.pop();
                    if(lefts.empty())
                    {
                        ans = max(ans,i-last);
                    }
                    else{
                        ans = max(ans,i - lefts.top());
                    }
                }
                else{
                    last = i;
                }
            } 
        }
        return ans;
    }
};
posted @ 2019-11-18 15:47  曲径通霄  阅读(138)  评论(0编辑  收藏  举报