僅給定乙個收容'('跟')'以查詢包含有效括號的最長子字串的長度。
示例 1:輸入:"(()"
輸出:2 解釋:最長的有效括號子字串是"()"
示例 2:輸入:")()"
輸出:4 解釋:最長的有效括號子字串是"()("
對阿里巴巴騰訊位元組進行動態程式設計的直觀方法是分別計算以 i 開頭的最長有效括號(i 從 0 到 n - 1·),並從中取最大的括號。
*支援:Python
類解決方案: def longestvalidparentheses(self, s: str) -int: n = len(s) ans = 0 def validcnt(start): cnt 是 ) 減去 ( cnt = 0 ans = 0 for i in range(start, n): if s[i] =='(': cnt += 1 if s[i] == ')': cnt -= 1 if cnt < 0: return i - start if cnt == 0: ans = max(ans, i - start + 1) return ans for i in range(n): ans = max(ans, validcnt(i)) return ans
複雜性分析時間複雜度:$o(n 2)$Space複雜度:$o(1)$ 主要思想與傳統支架解決方案相同'('進入堆疊,遇到')'從堆疊中取出並計算兩個括號之間的長度。 因為本題中存在非法括號對,且找到有效括號對的最大長度,所以有兩點需要注意:
堆疊中儲存的是符號的下標當堆疊為空且當前掃瞄的符號為')',您需要將此符號作為拆分器放入堆疊中在堆疊中初始化 -1,如定界符語言支援:python、j**ascript、cppj**ascript 程式碼:
使用堆疊求解 var longestvalidparentheses = function (s) else }return longest;};
python code:
class solution: def longestvalidparentheses(self, s: str) -int: if not s: return 0 res = 0 stack = [-1] for i in range(len(s)):if s[i] == "(": stack.append(i) else: stack.pop() if not stack: stack.append(i) else: res = max(res, i - stack[-1]) return res
cpp code:
class solution else st.push(i); return ans; }
複雜性分析時間複雜度:$o(n)$Space複雜度:$o(n)$We可以使用解1中的計數方法。
從左到右迭代一次,分別記錄左右括號的個數。 如果右>左,則表示可以匹配的最後乙個點不能匹配到當前點,將左右重置為0,如果右==左,則可以匹配,有效括號長度為左+右,我們得到區域性最優解。 如果它大於全域性最優解,我們更新全域性最優解 值得注意的是,該貨幣對類似於這樣一來,更新全域性最優解的邏輯就永遠無法執行了。 一種方法是再次從右向左遍歷,具體參見 **。
類似的想法有哨兵元素,虛擬節點。 但是,此方法不能用於此問題。支援:J**A、Python3、CPP
j**a code:
public class solution else if (left == right) if (right > left) left = right = 0; for (int i = s.length() 1; i >= 0; i--)else if (left == right) if (left > right) return maxlength; }
python3 code:
class solution: def longestvalidparentheses(self, s: str) -int: ans = l = r = 0 for c in s: if c == '(': l += 1 else: r += 1 if l == r: ans = max(ans, l + r) if r > l: l = r = 0 l = r = 0 for c in s[::1]: if c == '(': l += 1 else: r += 1 if l == r: ans = max(ans, l + r) if r < l: l = r = 0 return ans
cpp code:
class solution left = 0, right = 0; for (int i = n - 1; i >= 0; -i) return ans; }
對於所有動態規劃問題,首先需要解決的是如何找到合適的子問題。 這個問題需要我們找到最長的一對有效括號,首先想到的就是定義dp[i] 是前 i 個字串的最長有效括號對的長度但是我們會發現,有了這樣的定義,我們找不到 dp[i] 和 dp[i-1] 之間的任何關係。 所以,我們需要找到乙個新的定義:定義dp[i] 是以第 i 個字元結尾的最長有效括號對長度.然後,讓我們通過以下示例看一下 dp[i] 和 dp[i-1] 之間的關係。
s = '(()'
從上面的例子中,我們可以觀察到以下結論(在描述中,i是圖中dp陣列的下標,s對應的下標應該是i-1,第i個字元的i以1開頭基本情況:空字串的最長有效括號對長度肯定為 0,即:dp[0] = 0;秒字元末尾的最長有效括號為 0,s 的長度字元末尾最長的有效括號對的長度也是 0,我們可以得出結論,最長的有效括號對不能以'('結尾,即:dp[1] = d[2] = 0;當 i 等於 3 時,我們可以看到 dp[2]=0 和 dp[3]=2,因為第 2 個字元 (s[1]) 和第 3 個字元 (s[2]) 成對;當 i 等於 4 時,我們可以看到 dp[3]=2 和 dp[4]=4,因為我們將第乙個字元 (s[0]) 和第 4 個字元 (s[3]);因此,我們可以得出結論,如果第乙個i字元和部分i-1-dp[i-1]字元成對,則 dp[i] = dp[i-1] +2,其中:i-1-dp[i-1] > = 1,因為字元 0 沒有意義;根據規則 3,我們發現 dp[5]=0 和 dp[6]=2,但顯然,dp[6] 應該是 6,但我們發現它可以"(()"跟"()"即 dp[i] += dp[i-dp[i]],即:dp[6] = 2 + dp[6-2] = 2 + dp[4] = 6 根據上述規則,我們按如下方式求解 dp 陣列:[0, 0, 0, 2, 4, 0, 6, 0],其中最長有效括號對的長度為 6。 以下是**:
*支援:Python3、CPP
python3 code:
類解決方案: def longestvalidparentheses(self, s: str) -int: mlen = 0 slen = len(s) dp = [0] *slen + 1) for i in range(1, len(s) +1: 有效括號不太可能以一對結尾'('如果 s[i - 1] == 在末尾'(': continue left_paren = i - 2 - dp[i - 1] if left_paren >= 0 and s[left_paren] == '(': dp[i] = dp[i - 1] +2 連線有效括號 if dp[i - dp[i]]:d p[i] += dp[i - dp[i]] 更新最大有效擴充套件長度 if dp[i] >mlen: mlen = dp[i] return mlen
cpp code:
class solution return ans; }
複雜性分析時間複雜度:$o(n)$Spatial複雜度:$o(n)$Point 3個特徵,需要檢查的字元是s[i-1]和s[i-2-dp[i-1]],根據定義:i-1 >= dp[i-1],但i-2不一定大於dp[i-1],因此需要檢查越界;第 4 點特徵是最容易遺漏的,沒有必要檢查違規,因為根據定義:i >= dp[i],所以 dp[i-dp[i]] 的邊界情況是 dp[0];20.有效括號,如果您判斷的更多'('跟')'和'[', ']', '',該怎麼辦?如果輸出不是長度,而是帶有任意一對有效括號的字串,該怎麼辦?