32. 最长有效括号

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

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

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

思路
道题是求最长的括号序列,比较容易想到用栈这个数据结构。基本思路就是维护一个栈,遇到左括号就进栈,遇到右括号则出栈,并且判断当前合法序列是否为最长序列。不过这道题看似思路简单,但是有许多比较刁钻的测试集。具体来说,主要问题就是遇到右括号时如何判断当前的合法序列的长度。比较健壮的方式如下:
(1) 如果当前栈为空,则说明加上当前右括号没有合法序列(有也是之前判断过的);
(2) 否则弹出栈顶元素,如果弹出后栈为空,则说明当前括号匹配,我们会维护一个合法开始的起点start,合法序列的长度即为当前元素的位置-start+1;否则如果栈内仍有元素,则当前合法序列的长度为当前栈顶元素的位置下一位到当前元素的距离,因为栈顶元素后面的括号对肯定是合法的,而且左括号出过栈了。
因为只需要一遍扫描,算法的时间复杂度是O(n),空间复杂度是栈的空间,最坏情况是都是左括号,所以是O(n)。

#include <string>
#include <stack>
#include <algorithm>
using namespace std;
class Solution {
public:
    int longestValidParentheses(string s) {
        if (s.empty()) return 0;
        stack<int> index;
        int maxCount = 0, startIndex = 0;
        for (int i = 0; i < s.length(); i++)
        {
            if (s.at(i) == '(') index.push(i);
            else
            {
                if (index.empty()) startIndex = i + 1;
                else
                {
                    index.pop();
                    if (index.empty()) maxCount = max(maxCount, i - startIndex + 1);
                    else { maxCount = max(maxCount, i - index.top()); }
                }
            }
        }
        return maxCount;
    }
};

int main(int argc, char* argv[])
{
    string s = ")()())";
    auto res = Solution().longestValidParentheses(s);
    return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。 示例 1: 示例 2: 代码
    vbuer阅读 3,762评论 0 0
  • 一般会用到两种解法,栈和动态规划,但是两种方法都需要考虑到外层括号包裹内层括号的情况,即外层内部包含有一个完整的有...
    渐行渐远_5305阅读 4,336评论 0 0
  • u14e阅读 1,657评论 0 0
  • 青春,有你,有我,有他。 “舞起来,一起舞起来,舞动中国梦让生活精彩。”最近晚上在校园里最常听到的一...
    程末1阅读 2,490评论 0 2
  • 今天是2016年11月21日,是我百日千言计划的第八篇,以始为终,以终为始。 以前,总听人说周一容易有周末假期综合...
    bommmmy阅读 3,262评论 0 0