leetcode32 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.

 

与之前NYoj上的基础括号匹配和补括号dp两个都不太一样,需要一种新的思路吧,leetcode的有些题意都说的不清楚,只说最长有效括号,样例给的情况不全,有点争议。

参考样例:

())()
())(()
))()())

反正最后的情况来看就是求最长的括号匹配序列的长度,中间有一个废括号隔开就算两个串。

解决方法:1)栈模拟   2)DP

 

1)栈模拟

分各种情况:

有些串比如

1.())(()()  结果为4

2. )()(()())结果为8,从第二个开始到结束都为“有效”的括号串,这里的有效就是在NYoj那道栈括号匹配基础题输出YES的一样。

 

然后就是用用栈模拟各种情况,这里用栈维护左括号的下标,遇到右括号就判断。如果遇到被割断的位置,因为右括号不会进栈,那么这里要用个lastPos记录这个位置,我觉得隔断肯定是),如果有多个(,取最上面的一个左括号的位置即可,刚好满足栈的性质。

eg:

())(((((()()(

到第一个右括号,但是右括号不会进栈,lastPos先是指到3,然后后面左括号无限进栈,碰到右括号了弹出最上面的左括号,如果此时空了,说明新串长度为pos-lastPos+1,这是为了统计(()())的情况,如果不为空,说明多个(,取top,pos-sta.top即可。

()())((()))

如果是这个,新串开始,栈进入三个左括号,遇到第一个右括号,弹出第一个左括号,更新非空下的Max,当前POS-top,继续右括号,弹出左括号,继续更新POS-top,第三个右括号,此时弹出左括号,栈空,当前POS+1-LastPos。遍历完毕return。O(n)时间复杂度。

 

#include <bits/stdc++.h>
using namespace std;

int main()
{
    freopen("in.txt","r",stdin);
    string s;
    cin>>s;
     stack<int> sta;
        int Max=0;
        int lastPos=0;
        for (int pos=0; pos<s.length(); pos++) {
            if (s[pos]=='(') //遇到左括号,直接存入。
               sta.push(pos);
            else { //遇到右括号,分情况讨论
                if (sta.empty()) //如果此时栈里左括号已经被消耗完了,没有额外的左括号用来配对当前的右括号了,那么当前的右括号就被单出来了,表明当前子串可以结束了,此时的右括号也成为了下一个group的分界点,此时右括号下标为index,所以下一个group的起始点为index+1,相当于skip掉当前的右括号。
                    lastPos=pos+1;
                else { //如果此时栈不空,可能有两种情况,1)栈正好剩下1个左括号和当前右括号配对 2)栈剩下不止1个左括号,
                   sta.pop();
                    if (sta.empty())  //栈pop()之前正好剩下1个左括号,pop()之后,栈空了,此时group长度为pos-lastPos
                        Max=max(Max, pos-lastPos+1);
                    else  //栈有pop()之前剩下不止1个左括号,此时额外多出的左括号使得新的group形成。如()(()())中index=4时,stack中有2个左括号
                        Max=max(Max, pos-sta.top());
                }
            }
        }
        cout<<Max;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值