LeetCode 最长有效括号(32题)

LeetCode 最长有效括号

@author:Jingdai
@date:2020.10.10

题目描述(32题)

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

  • 示例输入

    ")()())"
    
  • 示例输出

    4
    
  • 解释

    最长有效括号子串为 "()()"
    

思路

  • 方法1 dp

    动态规划,建立一个长度等于字符串长度的数组 dp[] ,数组 dp[i] 的值代表以 i 结尾的子串的最长有效括号长度。

    • 初始条件

      很明显,初始条件 dp[0] = 0

    • 求解过程

      1. s.charAt(i) == '(' 时,dp[i] = 0

      2. s.charAt(i) == ')'s.charAt(i-1) == '(' 时,dp[i] = dp[i-2] + 2

        如下图。

        在这里插入图片描述

      3. s.charAt(i) == ')'s.charAt(i-1) == ')' 时,若 s.charAt(i-1-dp[i-1]) == '(' ,则 dp[i] = dp[i-1] + 2 + dp[i-1-dp[i-1] - 1] 。如下图。

      在这里插入图片描述

    • 注意事项

      注意边界条件判断,即下标不要越界。

    代码见下面。

  • 方法2 stack

    首先你会发现一个有效括号的子串的任意位置处,它前面(包括自己)的 '(' 数总是大于等于 ')' 数,而当 ')' 数多的时候,它一定不是有效的括号串。利用这个性质,操作栈 stack

    遍历字符串,如果遇到 '(' ,将它的下标入栈;如果遇到 ')' ,表示可以弹出一个 '(' 与它配对,则弹栈,如果栈不为空,表示正确的构造了一个有效括号串,则以该下标结尾的有效子串长度为当前下标减去栈顶元素。如果栈为空,表示 ')' 多了,不能成为有效的括号串,则将当前的下标入栈,用作下一次使用。

    为了整个遍历的统一不用分情况讨论,在遍历前首先将一个 -1 压栈,表示最初有一个 ')' 在栈中。代码见下面。

  • 方法3 正反向遍历

    思路还是和栈有点类似,就是一个有效括号的子串的任意位置处,它前面(包括自己)的 '(' 数总是大于等于 ')' 数,而当 ')' 数多的时候,它一定不是有效的括号串。

    首先从头遍历字符串,记录一个 left 和一个 right 表示 '('')' 的数目。当 right > left 时,表示这里已经不可能有有效的括号串了,将 leftright 置为 0 继续进行遍历。当 left == right 时,代表已经找到了一个有效的括号串。更新长度。

    但是这种会漏掉一种情况,就是 '(' 一直大于 ')' 的情况,就会出现无法找到有效的括号串,比如 "(()" ,所以在利用同样的思路,从尾部开始遍历,这样就是当 '(' 多的时候,它一定不是一个有效的括号串,可以将第一次遍历漏掉的情况考虑到。当 right < left 时,将 leftright 置为 0 继续进行遍历。当 left == right 时,代表已经找到了一个有效的括号串。更新长度。代码见下面。

代码

  • 方法1

    public int longestValidParentheses(String s) {
          
        int[] dp = new int[s.length()];
    
        int longestLen = 0;
        
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值