题目:
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和用栈来做标记,都有用到O(N)的空间复杂度。其实O(N)的空间复杂度是不必要的,提出一个O(N)时间,O(1)空间的解法。
主要思路是正序逆序各遍历一次【正序需要遍历,逆序最差需要遍历】。
- 首先正向
- 像(()))这样会出现)多于(的地方很好做,把前面匹配的长度记录下来就好。
- 问题在于((()这样(始终多于)的地方怎么处理,怎么找到这里面符合条件的串。这个时候就需要逆向来解决它,实际就是剔除多余的(。
- 逆向
- 逆向遍历之前的(多于)的串,这串最多只会有一个而且一定是在最后。因为:如果出现了一个这样的串,它就有能力一直往后遍历,即它既能容纳(也能容纳)。
- 反过来,从)开始,直接在(多于)的地方即不合格的地方,把前面匹配的长度记录下来。在这个过程中,显然每一个)都会有(来匹配,找出了这个串中符合条件的串。
- 最后,因为有可能()一样多,也就是结束的时候很完美地匹配了,这个时候的长度也记录一下,返回这个过程中最大的长度。
public class Solution {
public int longestValidParentheses(String s) {
int left = 0 , len = 0 , tmpl = 0 , pos = -1;
for( int i = 0; i != s.length(); i++ ){
if( s.charAt(i) == '(' ){
left ++; tmpl ++;
}else{
left --;
if( left == -1 ){
if( tmpl > len ){
len = tmpl;
}
left = 0; tmpl = 0;
pos = i;
}else{
tmpl ++;
}
}
}
if( left > 0 ){
left = 0; tmpl = 0;
for( int i = s.length() - 1 ; i != pos; i-- ){
if( s.charAt(i) == ')' ){
left ++; tmpl ++;
}else{
left --;
if( left == -1 ){
if( tmpl > len ){
len = tmpl;
}
left = 0; tmpl = 0;
}else{
tmpl ++;
}
}
}
}
if( left == 0 ){
if( tmpl > len ) len = tmpl;
}
return len;
}
}