[LeetCode解題攻略] 20. Valid Parentheses

[LeetCode解題攻略] 20. Valid Parentheses

更新於 發佈於 閱讀時間約 6 分鐘

題目描述

給定一個僅包含字元 '(', ')', '{', '}', '['']' 的字串 s,確定輸入字串是否有效。

輸入字串在以下情況下有效:

  1. 左括號必須由相同類型的括號封閉。
  2. 左括號必須以正確的順序關閉。
  3. 每個右括號都有一個對應的相同類型的左括號。

範例 1
Input: s = "()"
Output: true

範例 2

Input: s = "()[]{}"
Output: true

範例 3

Input: s = "(]"
Output: false

範例 4

Input: s = "([)]"
Output: false

範例 5

Input: s = "([])"
Output: true


解題思路

此問題的核心在於檢查括號的匹配情況,適合使用 堆疊(Stack) 資料結構來模擬括號的開啟和閉合過程。當遍歷字串時:

  1. 如果遇到左括號,則將其推入堆疊。
  2. 如果遇到右括號,則檢查堆疊頂部是否是匹配的左括號:
    • 如果匹配,將堆疊頂部彈出;
    • 如果不匹配或堆疊為空,則返回 false。
  3. 最後,檢查堆疊是否為空,若是空則括號匹配有效,否則無效。

解法一:堆疊法

實現步驟

  1. 使用一個堆疊存儲遇到的左括號。
  2. 使用字典定義每種右括號與左括號的匹配關係。
  3. 遍歷字串:
    • 如果是左括號,將其推入堆疊;
    • 如果是右括號,檢查堆疊頂部是否匹配:若匹配,彈出堆疊頂部;若不匹配或堆疊為空,返回 false。
  4. 最後檢查堆疊是否為空。

程式碼實現 (Python)

class Solution:
def isValid(self, s: str) -> bool:
# 定義匹配關係的字典
matching = {')': '(', '}': '{', ']': '['}
stack = []

for char in s:
# 如果是右括號,檢查堆疊頂部是否匹配
if char in matching:
if stack and stack[-1] == matching[char]:
stack.pop() # 匹配成功,彈出堆疊頂部
else:
return False # 匹配失敗
else:
# 如果是左括號,壓入堆疊
stack.append(char)

# 最後檢查堆疊是否為空
return not stack

時間與空間複雜度

  • 時間複雜度:O(n),其中 n 是字串的長度,因為每個字元最多只會被處理一次。
  • 空間複雜度:O(n),最壞情況下堆疊需要存儲所有的左括號。

解法二:使用列表模擬堆疊

思路

與解法一類似,但通過提前檢查和縮減堆疊操作次數進行小幅度優化。

程式碼實現 (Python)

class Solution:
def isValid(self, s: str) -> bool:
# 定義匹配關係
matching = {')': '(', '}': '{', ']': '['}
stack = []

for char in s:
# 如果是右括號且匹配失敗,直接返回 False
if char in matching and (not stack or stack[-1] != matching[char]):
return False
elif char in matching:
stack.pop() # 匹配成功,彈出堆疊頂部
else:
stack.append(char) # 左括號壓入堆疊

# 如果堆疊為空,表示匹配成功
return not stack

時間與空間複雜度

  • 時間複雜度:O(n),與解法一相同。
  • 空間複雜度:O(n),與解法一相同。

總結

該問題中,堆疊法是一個經典解法,這個題目經常被用於考察對堆疊的理解與操作熟練度。熟練掌握後,可應用於類似的問題,如處理 HTML 標籤匹配、數學運算中的括號匹配等情境。

avatar-img
追極光的北極熊|軟體工程師的小天地
6會員
115內容數
歡迎來到我的部落格!這裡記錄了軟體工程師的日常生活點滴,並分享程式設計與演算法的實用教學。無論你是初學者還是有經驗的開發者,都能在這裡找到深入淺出的技術解析與實戰技巧。此外,我也會分享工作中的心路歷程與學習心得,讓你不僅學到技術,更能瞭解軟體開發的實際應用與挑戰。希望透過這個平台,能與你共同成長,激發對技術的熱情!
留言
avatar-img
留言分享你的想法!
給定一個Linked list的head,從這個Linked list的末尾刪除第 n 個節點並返回其head。
給定一個包含 n 個整數的陣列 nums,傳回所有唯一的四元組 [nums[a], nums[b], nums[c], nums[d]] 的數組,使得該答案滿足題目的每項要求。
給定一組字符串,找出它們的最長公共前綴 (Longest Common Prefix)。如果沒有公共前綴,返回空字串 ""。
給定一個包含 2 到 9 之間數字的字串,傳回該數字可以表示的所有可能的字母組合。以任意順序回傳答案。 參考附圖為數字對字母的映射(就像電話按鈕一樣)。
給定一個長度為 n 的整數數組 nums 和一個整數target,在 nums 中找到三個整數,使得總和最接近target。傳回三個整數的總和。可以假設每個輸入都有一個解決方案。
給定整數陣列nums,傳回所有三元組[nums[i], nums[j], nums[k]],使得i != j, i != k, j != k,且nums[i ] + nums[j] + nums[k] == 0。
給定一個Linked list的head,從這個Linked list的末尾刪除第 n 個節點並返回其head。
給定一個包含 n 個整數的陣列 nums,傳回所有唯一的四元組 [nums[a], nums[b], nums[c], nums[d]] 的數組,使得該答案滿足題目的每項要求。
給定一組字符串,找出它們的最長公共前綴 (Longest Common Prefix)。如果沒有公共前綴,返回空字串 ""。
給定一個包含 2 到 9 之間數字的字串,傳回該數字可以表示的所有可能的字母組合。以任意順序回傳答案。 參考附圖為數字對字母的映射(就像電話按鈕一樣)。
給定一個長度為 n 的整數數組 nums 和一個整數target,在 nums 中找到三個整數,使得總和最接近target。傳回三個整數的總和。可以假設每個輸入都有一個解決方案。
給定整數陣列nums,傳回所有三元組[nums[i], nums[j], nums[k]],使得i != j, i != k, j != k,且nums[i ] + nums[j] + nums[k] == 0。