LeetCode 32 Hard 最長合法括號對 Python
阿新 • • 發佈:2019-01-13
def longestValidParentheses(self, s): """ Solution Method 演算法:動規 思路: 我一開始想的是和最長迴文子串一樣,用一個二維陣列dp[i][j]來記錄到s[i:j+1]部分是不是valid括號 就像迴文子串一樣用動規陣列記錄valid情況,而不是直接記錄最長的子串長。這樣的話還是要ON2K,ON2是因為 要兩層for,k是因為,在判斷諸如"(()())"這樣的情況時,我需要一個變數k去遍歷這個substring判斷會不會 在某個位置k使得dp[i][k]和dp[k+1][j] 都是True,如果有的話就說明dp[i][j] == T,這樣時間複雜度還是 沒有下來 題解的這種解法也算是比較巧妙了,直接用一維陣列記錄第i個位置結尾的最長子串的長度 顯然只有第i個位置是")"的時候,才可能在該位置形成合法串,然後先看i-1,如果i-1是'('的話,那麼顯然 dp[i] = dp[i-2]+2,就是在前面的基礎上再加2這樣 否則如果i-1的字元也是')'的話,就應該根據dp[i-1]找到前一個位置形成子串的最長的左側的那個'(', 這個位置是i-dp[i-1],前一個字元就是k = i-dp[i-1]-1,如果k是'('的話,那麼如果dp[i] = dp[i-1]+2+before before就是dp[k-1]的情況,把前面的加起來補上 """ if len(s) < 2: return 0 ans = 0 dp = [0] * len(s) for i in range(1, len(s)): if s[i] == ')': if s[i - 1] == '(': dp[i] = dp[i - 2] + 2 elif s[i - 1] == ')' and i - dp[i - 1] > 0: k = i - dp[i - 1] - 1 if s[k] == '(': before = dp[k - 1] if k >= 2 else 0 dp[i] = dp[i - 1] + 2 + before ans = max(ans, dp[i]) return ans def longestValidParentheses1( s): """ Solution method 2 演算法:棧 思路: 用棧來維護合法的括號對位置,在匹配的過程中就記錄下來最長的括號對 匹配的過程就和普通的驗證一樣,左括號入棧,右括號來的時候出棧,匹配 這裡棧內的棧頂表示的是【當前合法左括號的起始位置】!所以棧記憶體的是下標 在遍歷過程中,用i-top,即i-stack[-1]來計算合法的括號長度,0,1,1-0要+1才等於2, 所以先在棧記憶體一個數字-1,保障當出現()這樣的括號時,是能根據棧頂stack[-1] = -1 計算出長度1-(-1) = 2 然後還是左括號入棧,右括號來了,如果棧不空,出棧,計算長度,如果棧空的話,將右括號的位置入棧,此時 就相當於是記錄下了合法左括號前的那個位置,就像上面提到的0,1,0前面的-1一樣,從而保障能用i-stack[-1] 獲得當前最長的子串的起始位置,然後一減就是長度 多想想這個例子就通了"()((()))",'()))()()' """ if len(s) < 2: return 0 stack = [-1] ans = count = 0 for i in range(len(s)): if s[i] == '(': stack.append(i) else: stack.pop() if not stack: stack.append(i) count = i - stack[-1] if count > ans: ans = count return ans