问题连接:https://oj.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.
问题分析:这题需要扫两次,但是必须是完全合法的(就是(和)相同)才计算结果。否则会出现误算。但因为必须合法才计算结果,单方向扫总会忽略掉最后一块儿可能出现的更优解。所以需要左右各扫一遍然后比较大小。复杂度时间ON,空间O1. 代码如下:
public int longestValidParentheses(String s) {
int leftres = 0, rightres = 0;
int cur_res = 0;
int match_candidate = 0;
for(int i = 0; i < s.length(); i++){
if(s.charAt(i) == '('){
match_candidate++;
}else{
if(match_candidate > 0){
match_candidate--;
cur_res += 2;
if(match_candidate == 0)
leftres = Math.max(leftres, cur_res);
}else{
cur_res = 0;
}
}
}
cur_res = 0;
match_candidate = 0;
for(int i = s.length() - 1; i >= 0; i--){
if(s.charAt(i) == ')'){
match_candidate++;
}else{
if(match_candidate > 0){
match_candidate--;
cur_res += 2;
if(match_candidate == 0)
rightres = Math.max(rightres, cur_res);
}else{
cur_res = 0;
}
}
}
return Math.max(leftres, rightres);
}
曾经被面试官批评过具有重复逻辑的代码段不进行简化。所以这一次稍微换了一种方式稍微精简了一下代码段:
public int longestValidParentheses(String s) {
return Math.max(traverseMatch(s, false), traverseMatch(s, true));
}
public int traverseMatch(String s, boolean isLeft){
int currentResult = 0;
int currentSingle = 0;
int currentMatch = 0;
int i = isLeft ? 0 : s.length() - 1;
while((isLeft && i < s.length()) || (!isLeft && i >= 0)){
char currentChar = s.charAt(i);
if(currentChar == '(' && isLeft || currentChar == ')' && !isLeft){
currentSingle++;
}else{
if(currentSingle > 0){
currentSingle--;
currentMatch += 2;
if(currentSingle == 0)currentResult = Math.max(currentResult, currentMatch);
}else
currentSingle = currentMatch = 0;
}
if(isLeft)i++;
else i--;
}
return currentResult;
}
2018-09-15 updated
再补充几个简单的点:
1. 必须在currentSingle = 0 的时候才计算,否则会出现譬如()(()的时候,currentMatch = 4但实际结果并不为4的情况
2. 如果单边计算,会出现譬如((())的时候,因为没有出现currentSingle = 0的情况没有计算的情形。