LeetCode - Longest Valid Parentheses

https://leetcode.com/problems/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.

这道题是典型的DP题,DP的数组是一个一维数组,valid[i]记录的是以第i个字符为结尾的最长valid parentheses。

变化规律是:

第0个字符只有一个字符,肯定是0

如果第i个字符是‘(’,那么以这个为结尾的肯定不合法,当前值为0.

如果第i个字符是’)‘,那么看它前面第(i-1)个字符:

- 如果(i-1)是’)‘那么就看 第 i-valid[i-1]-1个字符,如果这个字符是’(‘,那么刚好和第i个字符组合,然后加上他们中间的,即从 i-valid[i-1]-1到 i 可以组合成类似 (()())这种情况,但这时要注意,目前组成的有效长度之前可能还有有效长度,如()(()())这种情况,就还得加上valid[i-valid[i-1]-2]的值,连起来才是总的长度。

- 如果(i-1)是'('的话,那么至少 i-1和i可以组成一个长度为2的有效字符串,然后再加上valid[i-1]就可以了

public class Solution {
    public int longestValidParentheses(String s) {
        if(s==null || s.length()==0) return 0;
        int max = 0;
        int[] valid = new int[s.length()];
        valid[0] = 0;    //longest valid substring end at position i
        for(int i=1; i<s.length(); i++){
            if(s.charAt(i)=='(') valid[i]= 0;
            else{
                if(s.charAt(i-1)=='('){
                    valid[i]=2;
                    if(i>1) valid[i]+=valid[i-2];
                }
                else{
                   if(valid[i-1]>0 && (i-valid[i-1]-1)>=0 && s.charAt(i-valid[i-1]-1)=='('){
                       valid[i] = 2+valid[i-1];
                       if((i-valid[i-1]-2)>=0) valid[i] += valid[i-valid[i-1]-2];
                   }
                }
            }
            max = Math.max(valid[i], max);
        }
        return max;
    }
}

空间复杂度O(n),时间复杂度O(n)

这个代码的各种分支也是可以合并的,见这里:

http://bangbingsyb.blogspot.com/2014/11/leetcode-longest-valid-parentheses.html

public class Solution {
    public int longestValidParentheses(String s) {
        if(s==null || s.length()==0) return 0;
        int max = 0;
        int[] valid = new int[s.length()];
        valid[0] = 0;    //longest valid substring end at position i
        for(int i=1; i<s.length(); i++){
            int j = i-valid[i-1]-1;
            if(s.charAt(i)=='(' || j<0 || s.charAt(j)==')') valid[i]= 0;
            else{
                valid[i] = valid[i-1]+2;
                if(j>0) valid[i]+=valid[j-1];
                max = Math.max(valid[i], max);
            }
        }
        return max;
    }
}
合并后的代码更简洁,但是可读性稍微差一点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值