欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

LeetCode-32.Longest Valid Parentheses最长有效括号子串

程序员文章站 2022-07-16 10:22:00
...

问题描述: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.
大致意思就是,给定一个只含有“(”和“)”的字符串,找出里面最长的有效子串的长度。

解决思路:考虑以字符串从0到n-1每一个字符结尾的最长有效子串的长度,然后返回最大值。

  1. 如果以“(”结尾,那么这肯定不是一个有效子串,故长度为0
  2. 如果以“)”结尾:那么就考虑 i 前面的最长有效子串
( ) ( ( ) ( ) )
index 0 1 2 3 4 5 6 7
len_value 0 2 0 0 2 0 4 8


LeetCode-32.Longest Valid Parentheses最长有效括号子串
假设整形数组dp[]记录着每个位置结尾的最长有效子串的长度
假设图中的五个圈是五个有效子串,由上图和上表可以看出,如果要求 i+1 位置结尾的最长有效子串,那么首先要求出从 i 位置结尾,j 位置开头的有效子串,如果 j-1 位置刚好与 i+1 位置相匹配,那么以 i+1 结尾的有效子串就是从 j-1 位置到 i+1 位置,即 dp[i]+2 。但是,由于我们要求的是最长有效子串,如果 j-2 结尾的也是有效子串,即 j-2 == k ,那么,按照上面的方法就少加了一段,所以还要加上dp[ j-2 ],这样才能算是以 i+1位置结尾的最长有效,即 dp[ i+1 ]=dp[ i ]+2+dp[ j-2 ]。

代码如下:

public class Solution {
    public int longestValidParentheses(String s) {
        if(s==null||s.equals("")){
            return 0;
        }
        char[] chs=s.toCharArray();
        int[] dp=new int[chs.length];//以某个位置结尾的最长子数组的长度,整形数组的初始值就是0
        int pre=0;//pre是i前面最长子数组前面的一个下标,判断pre和i是否匹配
        int len=0;
        for(int i=1;i<chs.length;i++){
            if(chs[i]==')'){
                pre=i-dp[i-1]-1;
                if(pre>=0&&chs[pre]=='('){
                    dp[i]=dp[i-1]+2+(pre>0?dp[pre-1]:0);          
                }
            }
            len=(dp[i]>len?dp[i]:len);
        }
        return len;

    }
}