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