最长有效括号

这是一篇关于解决括号问题的博客,主要讨论了两种方法:括号计数和栈的应用。通过两次遍历解决最长有效括号子串的问题,同时探讨了如何处理特殊情况如'('和')'的计数,以及 '*' 在有效括号字符串中的作用。文章提供了具体的代码实现。
摘要由CSDN通过智能技术生成

32. 最长有效括号

给你一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长有效(格式正确且连续)括号子串的长度。

示例 1:

输入:s = "(()"
输出:2
解释:最长有效括号子串是 "()"

示例 2:

输入:s = ")()())"
输出:4
解释:最长有效括号子串是 "()()"

来源:力扣(LeetCode)
这一题真的太有意思了,栈,动态规划,还有括号计数,都是很方便很巧妙的方法,但我只会最low的暴力求每个子串的最大长度,哈哈😭

(一)

先说说括号计数的方法吧,顾名思义就是计数左右括号出现的次数

这种方法需要两次遍历,一次左到右,还有一次右到左,两者的顺序无所谓

先说说思路:
(从左往右遍历的时候)
遍历的时候用两个变量L和R记录左右括号出现的次数,一旦R>L,就说明当前遍历到的子串无效,为什么呢?因为多出来了一个左括号的话,只要右边还有右括号,就可以和左括号配对,还是有可能有效的,但是如果多出来一个右括号,那就没救了,没人和你配对啊,一直是多余的

然后当可能有人会问,只要左括号等于右括号,就一定有效吗?
对于一个完成了的序列来说,这个判断条件自然不成立,
比如

))((

但是我们是在一个一个的遍历啊,一开始就是右括号的话,R不就大于L了吗,那么将这个点作为开头的可能性都被我们抛弃了,所以在L == R的时候是可以保证括号的有效性的

缺陷:
虽然计数很方便,但是有一个致命的缺陷,那就是忽略了 L一直大于R的情况,比如

(((((((()

很明显这一串的最长有效括号为2,即最后面的()但是计数只能在L == R的时候保证括号的有效性,即只有在L = = R的时候才敢记录长度,却又只敢在R > L是舍弃当前位置,于是遍历上面的序列时,一直不舍弃,但又一直不敢记录长度,于是直到最后,R也没有等于L,
直到最后也没有记录长度,一直为0

但是这种缺陷也很容易解决,只要再来一次从右往左的遍历就行了!这就是上面所说的为什么要遍历两次的原因。

从右往左遍历的话就解决了L 一直大于 R的情况,两次遍历,互相弥补缺点

右往左的遍历其实和左往右差不多,改一下遍历顺序,改一下跳过条件就ok了

代码:

class Solution {
   
public:
    int longestValidParentheses(string s) {
   
        int L = 0, R = 0, maxLength = 0;
        for(int i = 0;i<s.size();++i)//左往右
        {
   
            if(s[i]=='(')   ++L;//记录左括号
            else            ++R;//记录右括号
            //一旦两者相等,(就记录当前长度),不过依题意,我们要取最大长度
            if(L == R)      maxLength = max
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

timathy33

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值