[LeetCode解題攻略] 44. Wildcard Matching

更新 發佈閱讀 6 分鐘

題目描述

給定一個輸入字串 s 和一個Pattern p,其中:

  • s 是輸入字串,只包含小寫字母。
  • p 是匹配模式字串,可能包含以下特殊字元:
    • ? 可以匹配任何單個字元。
    • * 可以匹配任意長度(包括 0)的一段字元。

要求實現一個能夠支援字元*?的Wildcard Pattern Matching的函式。


範例 1

輸入: s = "aa", p = "a"
輸出: false
解釋: "a" 只能匹配一個 'a',而非兩個。

範例 2

輸入: s = "aa", p = "*"
輸出: true
解釋: '*' 可以匹配任意字元序列。

範例 3

輸入: s = "cb", p = "?a"
輸出: false
解釋: '?' 可以匹配 'c',但 'a' 無法匹配 'b'

解題思路

這題類似於正則表達式匹配,但難度更高,因為我們需要處理 *? 的匹配規則。根據問題特性,有以下幾種解法。


解法一:動態規劃

思路

  1. 使用一個二維 DP 陣列 dp,其中 dp[i][j] 表示 s 的前 i 個字元與 p 的前 j 個字元是否匹配。
  2. 初始化
    • dp[0][0] = True:空字串和空模式匹配。
    • dp[0][j] = True,當 p[1..j] 全是 * 時。
    • 其他情況初始化為 False。
  3. 遞推公式
    • 如果 p[j-1] == s[i-1] 或 p[j-1] == '?',則 dp[i][j] = dp[i-1][j-1]。
    • 如果 p[j-1] == '*',則 dp[i][j] = dp[i-1][j] or dp[i][j-1]:dp[i-1][j] 表示 * 匹配多個字元。dp[i][j-1] 表示 * 匹配 0 個字元。
  4. 返回結果dp[len(s)][len(p)]

程式碼

class Solution:
def isMatch(self, s: str, p: str) -> bool:
m, n = len(s), len(p)
# 初始化 DP 陣列
dp = [[False] * (n + 1) for _ in range(m + 1)]
dp[0][0] = True

# 初始化 p 開頭為 '*' 的情況
for j in range(1, n + 1):
if p[j - 1] == '*':
dp[0][j] = dp[0][j - 1]

# 填充 DP 陣列
for i in range(1, m + 1):
for j in range(1, n + 1):
if p[j - 1] == s[i - 1] or p[j - 1] == '?':
dp[i][j] = dp[i - 1][j - 1]
elif p[j - 1] == '*':
dp[i][j] = dp[i - 1][j] or dp[i][j - 1]

return dp[m][n]

時間與空間複雜度

  • 時間複雜度:O(m*n),其中 m 是 s 的長度,n 是 p 的長度。
  • 空間複雜度:O(m*n),用於存儲 DP 陣列。

解法二:雙指針法

思路

  1. 使用兩個指針:
    • i 遍歷 s。
    • j 遍歷 p。
  2. 記錄最近一次 * 出現的位置,以及當前匹配到的字串位置。
  3. 當匹配失敗時,回溯到上一個 * 的位置,並嘗試擴展匹配的長度。
  4. 如果模式中所有的 * 都被嘗試過,則匹配失敗。

程式碼

class Solution:
def isMatch(self, s: str, p: str) -> bool:
m, n = len(s), len(p)
i = j = 0 # 指向 s 和 p 的指針
star_index = -1
match_index = 0

while i < m:
# 當字元匹配或遇到 '?' 時
if j < n and (p[j] == s[i] or p[j] == '?'):
i += 1
j += 1
# 遇到 '*',記錄星號的位置,並假設它匹配 0 個字元
elif j < n and p[j] == '*':
star_index = j
match_index = i
j += 1
# 匹配失敗但之前有星號,回溯到星號
elif star_index != -1:
j = star_index + 1
match_index += 1
i = match_index
else:
return False

# 檢查剩餘的模式是否全是 '*'
while j < n and p[j] == '*':
j += 1

return j == n

時間與空間複雜度

  • 時間複雜度:O(m+n),其中 m 是 s 的長度,n 是 p 的長度。
  • 空間複雜度:O(1),只使用常數空間。

結論

  1. 如果需要簡潔高效的解法,雙指針法 是較好的選擇,適合處理大規模字串。
  2. 如果對於邊界條件需要嚴格檢查,則使用 動態規劃,較為直觀且容易調試。
  3. 這題的核心在於處理 *? 的靈活匹配,熟練掌握這些技巧後,類似題型的解法會更容易。

希望這篇解題教學對大家有幫助!


留言
avatar-img
追極光的北極熊|軟體工程師的小天地
16會員
173內容數
歡迎來到我的部落格!這裡記錄了軟體工程師的日常生活點滴,並分享程式設計與演算法的實用教學。無論你是初學者還是有經驗的開發者,都能在這裡找到深入淺出的技術解析與實戰技巧。此外,我也會分享工作中的心路歷程與學習心得,讓你不僅學到技術,更能瞭解軟體開發的實際應用與挑戰。希望透過這個平台,能與你共同成長,激發對技術的熱情!
2025/04/04
給定一個非負整數陣列 nums,其中 nums[i] 代表你在索引 i 處最多可以向右跳幾步。 請判斷是否能夠從索引 0 跳到最後一個索引。
2025/04/04
給定一個非負整數陣列 nums,其中 nums[i] 代表你在索引 i 處最多可以向右跳幾步。 請判斷是否能夠從索引 0 跳到最後一個索引。
2025/03/28
給定一個 m x n 的矩陣 matrix,請按照 螺旋順序(spiral order) 返回矩陣中的所有元素。
2025/03/28
給定一個 m x n 的矩陣 matrix,請按照 螺旋順序(spiral order) 返回矩陣中的所有元素。
2025/03/20
這道題是 LeetCode 的經典題之一,要求我們找出 一個子陣列,使其和最大,並返回這個最大和的數值。
2025/03/20
這道題是 LeetCode 的經典題之一,要求我們找出 一個子陣列,使其和最大,並返回這個最大和的數值。
看更多
你可能也想看
Thumbnail
5 月,方格創作島正式開島。這是一趟 28 天的創作旅程。活動期間,每週都會有新的任務地圖與陪跑計畫,從最簡單的帳號使用、沙龍建立,到帶著你從一句話、一張照片開始,一步一步找到屬於自己的創作節奏。不需要長篇大論,不需要完美的文筆,只需要帶上你今天的日常,就可以出發。征服創作島,抱回靈感與大獎!
Thumbnail
5 月,方格創作島正式開島。這是一趟 28 天的創作旅程。活動期間,每週都會有新的任務地圖與陪跑計畫,從最簡單的帳號使用、沙龍建立,到帶著你從一句話、一張照片開始,一步一步找到屬於自己的創作節奏。不需要長篇大論,不需要完美的文筆,只需要帶上你今天的日常,就可以出發。征服創作島,抱回靈感與大獎!
Thumbnail
題目敘述 題目會給我們一個字串s。 要求我們移除字串中的星號,還有刪除星號左手邊最靠近的第一個字元。 以字串的形式返回輸出答案。 題目的原文敘述 測試範例 Example 1: Input: s = "leet**cod*e" Output: "lecoe" Explanation:
Thumbnail
題目敘述 題目會給我們一個字串s。 要求我們移除字串中的星號,還有刪除星號左手邊最靠近的第一個字元。 以字串的形式返回輸出答案。 題目的原文敘述 測試範例 Example 1: Input: s = "leet**cod*e" Output: "lecoe" Explanation:
Thumbnail
當代名導基里爾.賽勒布倫尼科夫身兼電影、劇場與歌劇導演,其作品流動著強烈的反叛與詩意。在俄烏戰爭爆發後,他持續以創作回應專制體制的壓迫。《傳奇:帕拉贊諾夫的十段殘篇》致敬蘇聯電影大師帕拉贊諾夫。本文作者透過媒介本質的分析,解構賽勒布倫尼科夫如何利用影劇雙棲的特質,在荒謬世道中尋找藝術的「生存之道」。
Thumbnail
當代名導基里爾.賽勒布倫尼科夫身兼電影、劇場與歌劇導演,其作品流動著強烈的反叛與詩意。在俄烏戰爭爆發後,他持續以創作回應專制體制的壓迫。《傳奇:帕拉贊諾夫的十段殘篇》致敬蘇聯電影大師帕拉贊諾夫。本文作者透過媒介本質的分析,解構賽勒布倫尼科夫如何利用影劇雙棲的特質,在荒謬世道中尋找藝術的「生存之道」。
Thumbnail
見諸參與鄧伯宸口述,鄧湘庭於〈那個大霧的時代〉記述父親回憶,鄧伯宸因故遭受牽連,而案件核心的三人,在鄧伯宸記憶裡:「成立了成大共產黨,他們製作了五星徽章,印刷共產黨宣言——刻鋼板的——他們收集中共空飄的傳單,以及中國共產黨中央委員會有關文化大革命決議文的英文打字稿,另外還有手槍子彈十發。」
Thumbnail
見諸參與鄧伯宸口述,鄧湘庭於〈那個大霧的時代〉記述父親回憶,鄧伯宸因故遭受牽連,而案件核心的三人,在鄧伯宸記憶裡:「成立了成大共產黨,他們製作了五星徽章,印刷共產黨宣言——刻鋼板的——他們收集中共空飄的傳單,以及中國共產黨中央委員會有關文化大革命決議文的英文打字稿,另外還有手槍子彈十發。」
Thumbnail
題目敘述 題目會給定我們兩個字串。 第一個是指定順序的字串order。 第二個是輸入字串s。 要求我們依據order給定的順序,重新排列s。 如果出現order中沒有出現的字母,任意位置皆可。 合法答案可能不只一組,輸出其中一種即可。 題目的原文敘述 測試範例 Example
Thumbnail
題目敘述 題目會給定我們兩個字串。 第一個是指定順序的字串order。 第二個是輸入字串s。 要求我們依據order給定的順序,重新排列s。 如果出現order中沒有出現的字母,任意位置皆可。 合法答案可能不只一組,輸出其中一種即可。 題目的原文敘述 測試範例 Example
Thumbnail
當時間變少之後,看戲反而變得更加重要——這是在成為母親之後,我第一次誠實地面對這一件事:我沒有那麼多的晚上,可以任性地留給自己了。看戲不再只是「今天有沒有空」,而是牽動整個週末的結構,誰應該照顧孩子,我該在什麼時間回到家,隔天還有沒有精神帶小孩⋯⋯於是,我不得不學會一件以前並不擅長的事:挑選。
Thumbnail
當時間變少之後,看戲反而變得更加重要——這是在成為母親之後,我第一次誠實地面對這一件事:我沒有那麼多的晚上,可以任性地留給自己了。看戲不再只是「今天有沒有空」,而是牽動整個週末的結構,誰應該照顧孩子,我該在什麼時間回到家,隔天還有沒有精神帶小孩⋯⋯於是,我不得不學會一件以前並不擅長的事:挑選。
Thumbnail
給定一個字串陣列,請把它們所共有的字元伴隨著出現次數輸出。這篇文章介紹如何使用字典統計出現次數,和字典取交集的方法來解決此問題。並提供了複雜度分析和關鍵知識點。
Thumbnail
給定一個字串陣列,請把它們所共有的字元伴隨著出現次數輸出。這篇文章介紹如何使用字典統計出現次數,和字典取交集的方法來解決此問題。並提供了複雜度分析和關鍵知識點。
Thumbnail
Leetcode 精選75題 題目與題解 熱門考點 目錄 (持續更新中) 建議從左側目錄 或者 按Ctrl+F輸入關鍵字進行搜尋
Thumbnail
Leetcode 精選75題 題目與題解 熱門考點 目錄 (持續更新中) 建議從左側目錄 或者 按Ctrl+F輸入關鍵字進行搜尋
Thumbnail
題目敘述 題目會給定一個輸入字串s和一套編碼規則,要求我們針對字串s進行解碼,並且以字串的形式返回答案。 編碼規則: 數字[字串] -> []內的字串以對應倍數做展開,而且允許巢狀編碼。 例如: 3[a] 解碼完就是 aaa 2[bc] 解碼完就是 bcbc 2[a2[b]] = 2
Thumbnail
題目敘述 題目會給定一個輸入字串s和一套編碼規則,要求我們針對字串s進行解碼,並且以字串的形式返回答案。 編碼規則: 數字[字串] -> []內的字串以對應倍數做展開,而且允許巢狀編碼。 例如: 3[a] 解碼完就是 aaa 2[bc] 解碼完就是 bcbc 2[a2[b]] = 2
Thumbnail
題目敘述 題目會給我們一個字串s作為輸入,要求我們以white space空白為切割符號,切割出每個單字,並且反轉其順序後,以字串形式最為最後的輸出。 題目的原文敘述 測試範例 Example 1: Input: s = "the sky is blue" Output: "blue i
Thumbnail
題目敘述 題目會給我們一個字串s作為輸入,要求我們以white space空白為切割符號,切割出每個單字,並且反轉其順序後,以字串形式最為最後的輸出。 題目的原文敘述 測試範例 Example 1: Input: s = "the sky is blue" Output: "blue i
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
Thumbnail
題目敘述 題目會給我們兩個輸入,字串s和字串t,要求我們判定s是否為t的子序列(Subsequence)? 題目的原文敘述 測試範例 Example 1: Input: s = "abc", t = "ahbgdc" Output: true Example 2: Input:
Thumbnail
題目敘述 題目會給我們兩個輸入,字串s和字串t,要求我們判定s是否為t的子序列(Subsequence)? 題目的原文敘述 測試範例 Example 1: Input: s = "abc", t = "ahbgdc" Output: true Example 2: Input:
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News