题目:
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; } }
时间: 2024-10-15 07:02:30