1. 程式人生 > >LeetCode 之 Longest Valid Parentheses(棧)

LeetCode 之 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.

1.【基礎知識】
壓棧、彈棧機制能夠很好的模仿括號配對。

2.【屌絲程式碼】

  • 完成失敗!
  • 達成思想:

1)字串擷取,取到第一個'('為字串首元素;

2)字串的元素小於等於1,合法長度判斷為0;

3)依次查詢每一個正括號為首元素最長合法長度。

  • 卡殼部分

1)未能按'('間隔,迭代實現每一個正括號為首元素的最長合法長度。

3.【AC原始碼】

// LeetCode, Longest Valid Parenthese
// 使用棧,時間複雜度 O(n),空間複雜度 O(n)
class Solution {  
    public:  
        int longestValidParentheses(string s) {  
            int max_len = 0, last = -1; // the position of the last ')'  
            stack<int> lefts; // keep track of the positions of non-matching '('s  
            for (int i = 0; i < s.size(); ++i) { 
				
                if (s[i] =='(') 
				{  
                    lefts.push(i);  
                }   
                else 
				{  
                    if (lefts.empty()) 
					{  
                        // no matching left  
                        last = i;  
                    }   
                    else 
					{  
                        // find a matching pair  
                        lefts.pop();  
                        if (lefts.empty())
						{  
                            max_len = max_len>=i-last?max_len:i-last;  
                        }   
                        else
						{  
                            // lefts.top() 表示上一個未匹配的正括號
							// i-lefts.top() 表示已匹配括號長度
							max_len = max_len>=i-lefts.top()?max_len:i-lefts.top();  
                        }  
                    }  
                }
            }  
        return max_len;  
    }  
}; 
4.【覆盤】

1)腦子沒想好就不要動手寫程式碼,寫程式碼也是信馬由繮毫無效率,思路不成熟的上手,在有限時間內,對任務的完成只會徒增恐懼感與無助感;

2)對於一個沒想清楚的問題,去反問一句這是不是關鍵問題,如果是,就把它想透再下手!

比如本例:最相近的兩個符號找到之後,它們是不是一定成對,如果成對接下去是怎麼辦?之前和之後的操作分別是什麼?!堅決將這個問題的求解出來的態度是偉大光榮而正確的!

因此,最先應該思考的不是問題,而是第一個元素怎麼開始,進而中間的數值怎麼半,邊界值會讓你關注細節而忽略巨集觀!

3)因為筆者總有string.find()方法在腦子裡面繞,這只是看起來使迴圈似乎變得簡單,只是表面上覺得比簡單的i++快。

實質上這並不減少計算的時間,往往還會因為方法的呼叫而費時耗存!

4)為什麼這裡的成員函式的字串不是作為常量字串的?竊以為,將字串作為引數輸入,不如將 const string 作為輸入更合理!

5.【演算法核心思想】

1)從字串第一個元素開始,正壓棧反彈棧;

2)當次迴圈未壓棧,且棧空,說明出現連續空棧,成對失連;

3)當次迴圈未壓棧,彈棧後棧空,成對暫未失連,則計算當次連續對相對上次失連元素遞增數,錄入;

4)當次迴圈未壓棧,彈棧後棧非空,成對情況未失連,則計算當次連續對相對棧頂元素遞增數,錄入。