LeetCode - Longest Valid Parentheses

来源:互联网 发布:excel查询数据库 编辑:程序博客网 时间:2024/06/03 19:56

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;    }}
合并后的代码更简洁,但是可读性稍微差一点

0 0