longestValidParentheses

更新 發佈閱讀 7 分鐘

在解longestValidParentheses的時候一開始思路是這樣

raw-image

由於"()"一直失敗所以問AI

他跟我說

你的原始程式碼出問題,不是「語法錯」而是方法論本質錯


而我幫你做的那個 two-pass 左右掃描法,是一個完全不同的演算法,雖然乍看和你的「左右指針」很像,但本質完全不是同一回事。


下面我用超清楚的方式告訴你:

🔥 你原本的程式碼的核心邏輯(錯誤根源)

你的邏輯是這樣:

  1. 左指針從左找第一個 '('
  2. 右指針從右找第一個 ')'
  3. 找到後就直接回傳中間的長度

也就是這段:

if s[l] == "(" and s[r] == ")":
return len(s[l:r])

❌ 問題 1:切片不包含 r

"()"s[0:1] = "(" → 長度 = 1


而答案應該是 2



❌ 問題 2:這個方法根本不會檢查「中間是否合法」

例如:

s = "())(()"

你只是在找最外層的 ( 和 )


但是 longest valid 在中間,不在外層。


也就是:

你的方法是在找:

(            )
^ ^
l r

然而題目要的其實是:

     ()()

兩者邏輯完全不同。


❌ 問題 3:你只找一次就 return

所以你 永遠只能找到一段,而且一定是最外面那段


但最外層常常是「不合法的」。



⭐ 那我到底「做了什麼」讓它能過?

我用了一個叫做:

👉 Two-Pass Scan(左右掃描平衡法)

這個方法的核心思想是:

✔ 用 left 計算 ( 數量

✔ 用 right 計算 ) 數量

✔ 當 left == right 時,表示這一段是合法的

✔ 當 right > left(或反方向 left > right)代表這一段無效,重置


🔥 用圖解讓你看差異

假設 s = "(()())"

你的方法:

找最外層 → 直接 return "(()())" → 其實這裡竟然是合法的,但如果外層不合法就慘了。


而且你用 slicing 會漏掉右邊字元。



我的方法:

左→右掃描:

每看到一個 '(' 就 +1


每看到一個 ')' 就 +1 只要數字平衡,就表示是一段 valid:


( ( ) ( ) )
1 2 1 2 1 2

每次 numbers 平衡 → 更新答案

但左→右有個問題:

")()())" 開頭多一個 ) → 就會破壞計算。

所以:


再右→左掃描:

同樣計算 balance,但反過來保證:

)))((()))

這種左多的也能處理。


🌟 本質上的差異:

❌ 你的方法是假設「最外層配對成功 → 中間就一定合法」

這是不成立的。

就像:

(   )  <-- 外層配對成功
) ( <-- 中間其實是亂的

✔ 我的 two-pass 方法是在檢查「每一段是否平衡」,不是只看外層。

這才是真正能 AC 的邏輯。


🎯 你真正學到的點

你的方法錯在:

  • 「夾左右」這個策略 不會產生有效括號 substring 的長度
  • 無法處理 nested / broken / segmented cases
  • slicing 會漏掉末端字元
  • 只配一次外層就 return → 根本不是在找 longest

我做的是:

  • 使用計數平衡(balance counting)
  • 左掃描一次,右掃描一次
  • 檢查所有可能的有效段落
  • 更新最長合法區間


       所以最後答案是

raw-image


raw-image

時間複雜度:O(n)

程式掃描字串兩次:

  1. 左 → 右 一次 O(n)
  2. 右 → 左 一次 O(n)

加起來:

O(n) + O(n) = O(n)

沒有巢狀迴圈,也沒有額外扫描。

最終時間複雜度 = O(n)


空間複雜度:O(1)

整段程式使用的變數:

left
right
ans
c(迴圈變數)

都是 固定數量 的整數,而且不會依字串長度增加。

也沒有 stack、array、dictionary。

因此:

空間複雜度 = O(1)(常數空間)

raw-image


raw-image
raw-image
raw-image


raw-image
class Solution:

    def longestValidParentheses(self, s: str) -> int:

        left = right = 0

        ans = 0

       

        # 左到右

        for c in s:

            if c == '(':

                left += 1

            else:

                right += 1



            if left == right:

                ans = max(ans, 2 * left)

            elif right > left:

                left = right = 0



        left = right = 0

       

        # 右到左

        for c in reversed(s):

            if c == ')':

                right += 1

            else:

                left += 1



            if left == right:

                ans = max(ans, 2 * left)

            elif left > right:

                left = right = 0



        return ans

留言
avatar-img
留言分享你的想法!
avatar-img
于正龍(Ricky)的沙龍
54會員
86內容數
人工智能工作經驗跟研究
2025/12/04
36. Valid Sudoku Medium Topics premium lock icon Companies Determine if a 9 x 9 Sudoku board is valid. Only the filled cells need to be validated acco
Thumbnail
2025/12/04
36. Valid Sudoku Medium Topics premium lock icon Companies Determine if a 9 x 9 Sudoku board is valid. Only the filled cells need to be validated acco
Thumbnail
2025/12/03
class Solution:     def isMatch(self, s: str, p: str) -> bool:         # i = s 的指標(小蛇目前走到哪)         # j = p 的指標(迷宮目前在哪個門)         i = 0         j
2025/12/03
class Solution:     def isMatch(self, s: str, p: str) -> bool:         # i = s 的指標(小蛇目前走到哪)         # j = p 的指標(迷宮目前在哪個門)         i = 0         j
2025/11/30
Sudoku 是經典的 Constraint Problem(約束問題)。 題目要求你把空格 . 填入 1~9,使得: 每一列(row)數字 1~9 各出現一次 每一行(column)數字 1~9 各出現一次 每一個 3×3 box(九宮格)數字 1~9 各出現一次 這種問題最典型
2025/11/30
Sudoku 是經典的 Constraint Problem(約束問題)。 題目要求你把空格 . 填入 1~9,使得: 每一列(row)數字 1~9 各出現一次 每一行(column)數字 1~9 各出現一次 每一個 3×3 box(九宮格)數字 1~9 各出現一次 這種問題最典型
看更多
你可能也想看
Thumbnail
這是什麼大問題嗎?這樣就寫一篇文章,會不會太混了! 會! 其實蠻混的! 哈哈哈! 1.英文不好,乾脆用中文。就用微軟 Copilot 設計工具 的網址在此。好啦!
Thumbnail
這是什麼大問題嗎?這樣就寫一篇文章,會不會太混了! 會! 其實蠻混的! 哈哈哈! 1.英文不好,乾脆用中文。就用微軟 Copilot 設計工具 的網址在此。好啦!
Thumbnail
題目敘述 Longest Palindromic Substring 給定一個輸入字串s,請找出最長的回文子字串。 答案可能不只一個,回傳任何一個合法的答案皆可。
Thumbnail
題目敘述 Longest Palindromic Substring 給定一個輸入字串s,請找出最長的回文子字串。 答案可能不只一個,回傳任何一個合法的答案皆可。
Thumbnail
給定一個字串s,以s擁有的字元製造迴文字串。要能製造出的迴文字串長度最長是多少,觀察迴文字串不外乎兩種模式對稱部分 + 核心字元 + 對稱部分,其中,核心字元在正中央出現一次,或者 對稱部分 + 對稱部分。使用演算法統計出現次數並推理出盡可能充分利用每個字元的迴文字串製造方法。
Thumbnail
給定一個字串s,以s擁有的字元製造迴文字串。要能製造出的迴文字串長度最長是多少,觀察迴文字串不外乎兩種模式對稱部分 + 核心字元 + 對稱部分,其中,核心字元在正中央出現一次,或者 對稱部分 + 對稱部分。使用演算法統計出現次數並推理出盡可能充分利用每個字元的迴文字串製造方法。
Thumbnail
知道如何從一組給定的英文字母和單字庫中的單字拼出最高分的單字組合。使用DFS + 回溯法 + 剪枝優化的演算法,詳細分析瞭如何展開所有可能的路徑,並且找出符合條件的狀態,協助讀者理解演算法背後的思維和方法。
Thumbnail
知道如何從一組給定的英文字母和單字庫中的單字拼出最高分的單字組合。使用DFS + 回溯法 + 剪枝優化的演算法,詳細分析瞭如何展開所有可能的路徑,並且找出符合條件的狀態,協助讀者理解演算法背後的思維和方法。
Thumbnail
演算法映射化簡的核心觀念 在面對新題目的時候,除了重頭想一個新的演算法之外; 還有另一個方法,想看看有沒有核心觀念彼此相同的問題與演算法, 如果有,就可以把新的題目映射化簡到已知解法的問題,用已知的演算法去解開。 接著,我們會介紹幾個範例,並且使用映射化簡的技巧來解題,透過化
Thumbnail
演算法映射化簡的核心觀念 在面對新題目的時候,除了重頭想一個新的演算法之外; 還有另一個方法,想看看有沒有核心觀念彼此相同的問題與演算法, 如果有,就可以把新的題目映射化簡到已知解法的問題,用已知的演算法去解開。 接著,我們會介紹幾個範例,並且使用映射化簡的技巧來解題,透過化
Thumbnail
我問AI,結果得到的兩個完全相反的結果,老師在教學影片中說的是Claude的版本.... 在AI時代自學,除了要懂得下咒語(prompt,網路上到處在教如何下正確的prompt,使AI更好用),還是要有一定的基礎能力(例如查核能力),不要太相信AI給的答案,多問幾家總是好的。
Thumbnail
我問AI,結果得到的兩個完全相反的結果,老師在教學影片中說的是Claude的版本.... 在AI時代自學,除了要懂得下咒語(prompt,網路上到處在教如何下正確的prompt,使AI更好用),還是要有一定的基礎能力(例如查核能力),不要太相信AI給的答案,多問幾家總是好的。
Thumbnail
題目敘述 題目會給定我們一個字串s,要求我們反轉字串s中所有母音字元的順序,並且以字串的形式輸出。 註: 母音字元為a, e, i, o, u 或者 A, E, I, O, U 題目的原文敘述 測試範例 Example 1: Input: s = "hello" Output: "ho
Thumbnail
題目敘述 題目會給定我們一個字串s,要求我們反轉字串s中所有母音字元的順序,並且以字串的形式輸出。 註: 母音字元為a, e, i, o, u 或者 A, E, I, O, U 題目的原文敘述 測試範例 Example 1: Input: s = "hello" Output: "ho
Thumbnail
題目敘述 題目會給定我們兩個輸入字串word1, word2,要求我們依照word1,word2,word1,word2, ... 交叉前進的方式,合併兩個字串,作為輸出。 題目的原文敘述 測試範例 Example 1: Input: word1 = "abc", word2 = "pq
Thumbnail
題目敘述 題目會給定我們兩個輸入字串word1, word2,要求我們依照word1,word2,word1,word2, ... 交叉前進的方式,合併兩個字串,作為輸出。 題目的原文敘述 測試範例 Example 1: Input: word1 = "abc", word2 = "pq
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News