題目:
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.
題解:
這道題是求最長匹配括號的長度,而不是個數,我最開始想錯了,去寫個數去了。。。
題解引用自:http://codeganker.blogspot.com/2014/03/longest-valid-parentheses-leetcode.html
這道題是求最長的括號序列,比較容易想到用棧這個資料結構。基本思路就是維護一個棧,遇到左括號就進棧,遇到右括號則出棧,並且判斷當前合法序列是否為最
長序列。不過這道題看似思路簡單,但是有許多比較刁鑽的測試集。具體來說,主要問題就是遇到右括號時如何判斷當前的合法序列的長度。比較健壯的方式如下:
(1) 如果當前棧為空,則說明加上當前右括號沒有合法序列(有也是之前判斷過的);
(2)
否則彈出棧頂元素,如果彈出後棧為空,則說明當前括號匹配,我們會維護一個合法開始的起點start,合法序列的長度即為當前元素的位置
-start+1;否則如果棧內仍有元素,則當前合法序列的長度為當前棧頂元素的位置下一位到當前元素的距離,因為棧頂元素後面的括號對肯定是合法的,而
且左括號出過棧了。
因為只需要一遍掃描,演算法的時間複雜度是O(n),空間複雜度是棧的空間,最壞情況是都是左括號,所以是O(n)。
然後網上找了解法,有些人使用了DP,我沒仔細看。。主要還是吸取了棧的思想。程式碼引用自:http://rleetcode.blogspot.com/2014/01/longest-valid-parentheses.html, 個人稍作修改。
如下所示:
2 if (s==null||s.length()==0){
3 return 0;
4 }
5
6 int start=0;
7 int maxLen=0;
8 Stack<Integer> stack=new Stack<Integer>();
9
10 for (int i=0; i<s.length();i++){
11 if (s.charAt(i)=='('){
12 stack.push(i);
13 }else{
14 if (stack.isEmpty()){
15 // record the position before first left parenthesis
16 start=i+1;
17 }else{
18 stack.pop();
19 // if stack is empty mean the positon before the valid left parenthesis is "last"
20 if (stack.isEmpty()){
21 maxLen=Math.max(i-start+1, maxLen);
22 }
23 else{
24 // if stack is not empty, then for current i the longest valid parenthesis length is
25 // i-stack.peek()
26 maxLen=Math.max(i-stack.peek(),maxLen);
27 }
28 }
29 }
30 }
31 return maxLen;
32 }