LeetCode最长有效括号

LeetCode: Longest Valid Parentheses

问题描述

Given a string containing just the characters ‘(’ and ‘)’, find the length of the longest valid (well-formed) parentheses substring.

Example1

Input: s = “(()”
Output: 2
Explanation: The longest valid parentheses substring is “()”.

Example2

Input: s = “)()())”
Output: 4
Explanation: The longest valid parentheses substring is “()()”.

Example3

Input: s = “”
Output: 0

方法思路
动态规划:
首先设置一个整型数组 dp[i] , 表示以 s[i] 结尾的连续有效括号子串的长度,从左向右遍历 s[i],可能存在以下几种情况:

  • s[i] == ‘(’ ,因为以 ‘(’ 结尾肯定不是有效的括号子串,所以 dp[i] = 0.
  • s[i] == ‘)’ 时,可能存在以下多种情况:
    • 检验 s[i-1],当 s[i-1] == ‘(’ 时,形成了 “()”,括号子串的有效长度至少为2,进一步地,在已知 dp[i] == 2 的情况下,还需要检验 s[i-2] 是否存在
      • 如果 s[i-2] 存在并且 dp[i-2] != 0, 那么 dp[i] = dp[i-2]+2
      • 如果 s[i-2] 不存在或者 dp[i-2] == 0, dp[i] = 2
    • 检验 s[i-1],当 s[i-1] == ‘)’ 时, 形成了"))", 这种情况就需要先判断与 s[i-1] 匹配的括号的前一个括号是否存在
      • 如果存在并且是’(’,正好与 s[i] 相匹配,则 dp[i] 至少为 dp[i-1] + 2 ,另外还需要判断与 s[i] 相匹配的 ‘(’ 的前面是否还有有效的括号子串,位置为 i (当前子串的尾部) - 1(子串尾部前一个 ‘)’ ) - dp[i-1] ( i-1 对应的最长有效子串的长度) - 1(子串首部的’(’ )
        • 如果不存在,则 dp[i] = dp[i-1]+2
        • 如果存在, 则 dp[i] = dp[i-1]+2+dp[i-1-dp[i-1]-1]
      • 如果不存在, dp[i] == 0

栗子 “(()()))” :

i0123456
s(()()))
dp0020460

* 思路来自于 https://www.bilibili.com/video/BV17C4y1a7rs?from=search&seid=2289367917882798129&spm_id_from=333.337.0.0

代码如下(示例):

class Solution {
    public int longestValidParentheses(String s) {
        int[] dp = new int[s.length()];
        for(int i = 0; i < s.length(); i++){
            //If s[i] is '('
            if(s.charAt(i) == '('){
                dp[i] = 0;
            }
            //If s[i] is ')'
            else{
                if( i - 1 > -1){
                    //If s[i-1] is '(', we will get a valid parenthese "()"
                    if( s.charAt(i-1) == '('){
                        dp[i] = 2;
                        if( i - 2 > -1 && dp[i-2] != 0){
                            dp[i] = dp[i-2] + 2;
                        }
                    }
                    //If s[i-1] is ')', we will get "))"
                    else{
                        if( i-1-dp[i-1] > -1 && s.charAt(i-1-dp[i-1]) == '('){
                            if(i-1-dp[i-1]-1 > -1 && dp[i-1-dp[i-1]-1] != 0){
                                dp[i] = dp[i-1]+2+dp[i-1-dp[i-1]-1];
                            }else{
                                dp[i] = dp[i-1]+2;
                            }
                        }else{
                            dp[i] = 0;
                        }
                    }
                }else{
                    dp[i] = 0;
                }
                
            }
        }
        
        int max = 0;
        for(int i = 0; i < dp.length; i++){
            if(dp[i] > max){
                max  = dp[i];
            }
        }
        return max;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值