日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[LeetCode] Wildcard Matching 题解

發布時間:2025/4/14 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [LeetCode] Wildcard Matching 题解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

6. Wildcard Matching

題目

Implement wildcard pattern matching with support for '?' and '*'.

'?' Matches any single character.'*' Matches any sequence of characters (including the empty sequence).

The matching should cover the entire input string (not partial).

The function prototype should be:bool isMatch(const char *s, const char *p)

Some examples:isMatch("aa","a") ? falseisMatch("aa","aa") ? trueisMatch("aaa","aa") ? falseisMatch("aa", "*") ? trueisMatch("aa", "a*") ? trueisMatch("ab", "?*") ? trueisMatch("aab", "c*a*b") ? false

解答

DFS

這里的難點在于如何處理*,因為這個星號可以代表0到多個字符,而且有可能會遇到遞歸一開始匹配正確后面不正確,但實際上應該從后面開始匹配。

class Solution(object):# p為匹配模式,s為字符串def recursive(self, s, p, si, pi, cur):first = Truen_cur = curwhile si < len(s) and pi < len(p) and (s[si] == p[pi] or p[pi] == '?'):si += 1pi += 1if pi == len(p):return si == len(s)if p[pi] == '*':while pi < len(p) and p[pi] == '*':pi += 1if pi >= len(p):return Truefor i in range(si, len(s)):# 表明開始重合,從這里再度開始遞歸if p[pi] != s[i] and p[pi] != '?':continueif first:cur += 1first = False# 可能存在多次重合但是還不算真正匹配的情況if self.recursive(s, p, i, pi, cur + 1):return Trueif cur > n_cur + 1: # 正常來說n_cur = cur + 1return Falsereturn Falsedef isMatch(self, s, p):""" :type s: str :type p: str :rtype: bool """return self.recursive(s, p, 0, 0, 0)

這種做法超時。

DP

我們定義一個二維數組dp,橫坐標為待匹配字符串,縱坐標為模式字符串,dp[i][j]則代表到模式字符串從0到 i 對應待匹配字符串的的0到 j 是否是匹配的。舉個例子:

pattern = "a*bc" str = "abbc"

我們可以根據前面提到的畫出整個二維數組

\\abbc
\TFFFF
aFTFFF
*FTTTT
bFFTTF
cFFFFT

我們可以發現一個規律,每當遇到兩個字符不相等的時候,那么數組的值則肯定是False,相反相等的時候肯定是True,這里需要注意的是*,這里則需要考慮到它當前可能匹配0個字符串或者匹配多個字符,比如上面中的a*和ab的情況,此時我們需要發現a*及a或者a和ab其中有任何一個成功匹配的,它的結果也肯定為T。

這個狀態轉義方程要怎么推算出來呢?

  • 如果p.charAt(i)=='*','*'可以選擇匹配0個字符,此時flag[i][j]=flag[i-1][j];可以選擇匹配1個字符,此時flag[i][j]=flag[i-1][j-1];……所以可以得到下面的公式:

  • 因為flag[i][j]=flag[i-1][j]||flag[i-1][j-1]||……||flag[i-1][0],我們可以代入上面的公式得到:

  • 于是我們可以很簡單的寫出程序了(下面的程序的i,j和狀態轉義方程是相反的,但是原理是相同的)

    class Solution(object):# p為匹配模式,s為字符串def isMatch(self, s, p):""" :type s: str :type p: str :rtype: bool """if len(s) != len(p) - p.count('*'):return Falsenewp = ""i = 0while i < len(p):newp += p[i]if p[i] == '*':while i + 1 < len(p) and p[i + 1] == '*':i += 1i += 1sl, pl = len(s), len(newp)dp = [[False for x in range(pl + 1)] for y in range(sl + 1)]dp[0][0] = Trueif pl > 0 and p[0] == '*':dp[0][1] = Truefor x in range(1, sl + 1):for y in range(1, pl + 1):if newp[y - 1] != '*':dp[x][y] = dp[x - 1][y - 1] and (s[x - 1] == newp[y - 1] or newp[y - 1] == '?')else:dp[x][y] = dp[x - 1][y] or dp[x][y - 1]return dp[sl][pl]

    同樣的原理,我們還可以把它縮減成一維數組,你可以把它想象成在二維數組中計算每一行的數據,如果遇到*則更新當前行的數據;為什么可以這么做呢?我們可以根據前面提到的公式發現,其中當前的數據依賴于j的變化,也就是待匹配字符串的值,我們還需要在外面寫個模式串的循環,其實和二維數組的做法的時間復雜度是一樣的,但是縮減了空間,但是并不是所有的都可以這么做,這個取決于你的依賴項是什么。總而言之,其原理還是一樣的,只是想辦法讓它們的數據能夠共存到一維數組中。

    class Solution:# @return a booleandef isMatch(self, s, p):length = len(s)if len(p) - p.count('*') > length:return Falsedp = [True] + [False]*lengthfor i in p:if i != '*':# 因為依賴項是前面的值,所以不能從前面往后面掃,得從后往前計算for n in reversed(range(length)):dp[n+1] = dp[n] and (i == s[n] or i == '?')else:# 更新當前行的數據for n in range(1, length+1):dp[n] = dp[n-1] or dp[n]dp[0] = dp[0] and i == '*'return dp[-1]

    貪心算法

    下標描述
    si待匹配字符串的移動下標
    pi模式串的移動下標
    lastmatch上一次匹配的待匹配字符串的下標
    laststar上一次匹配的模式串的下標
  • 如果當前相等或者模式串中字符為?,則移動相互的下標即可;
  • 如果當前模式串字符為*,分別紀錄lastmatch、laststar,并且移動模式串下標,但是不移動待匹配字符串下標,因為可能存在匹配0個字符串的情況;
  • 如果當前相互對應的字符不再相等且不為*,如果前面有*號,說明之前的匹配失敗了,模式字符串下標回到之前紀錄laststar的后一位,不再移動,專門用來給待匹配字符串字符來匹配,這段時間內,si會不斷的向前移動,直到匹配到相互的值相等才移動模式字符串的下標;
  • 如果前面的情況都不符合,則肯定為False;
  • 看看我的抽象派畫風。

    class Solution(object):# p為匹配模式,s為字符串def isMatch(self, s, p):si, pi = 0, 0lastmatch, laststar = -1, -1sl, pl = len(s), len(p)if pl - p.count('*') > sl:return False# 注意條件順序while si < sl:if pi < pl and (s[si] == p[pi] or p[pi] == '?'):pi += 1si += 1elif pi < pl and p[pi] == '*':lastmatch, laststar = si, pi # 之所以不更新lastmatch是因為考慮到*只匹配0個字符串pi += 1# 再次進到這個判斷,說明當前下標對應的值不相等elif laststar != -1:pi = laststar + 1 # pi當前不是*,并且回到上一次星的后面,專門用來給si匹配lastmatch += 1 # 必須更新lastmatch,因為之前已經不想等,如果在回到開始的狀態就會陷入死循環si = lastmatchelse:return False# 可能存在p的末尾都是*的情況while pi < len(p) and p[pi] == '*':pi += 1# 最后匹配成功模式字符串的下標必然為其長度,表示已經匹配完成return pi == pl

    tips:不要小看保存你的長度值,如果你頻繁的用到的話,最好保存下來,比如在這里,我保存下來以后可以讓我提升%10的beat submissions!

    一樣的原理,但是使用了遞歸的方式來做

    class Solution(object):def isMatch(self, s, p):""" :type s: str :type p: str :rtype: bool """seen = {}wild_single, wild_multi = "?", "*"# seen has the pattern - source tuple as key, and bool result as successsource, pattern = s, pdef is_match(sindex, pindex):key = (sindex, pindex)if key in seen:return seen[key]result = True# if there's no string, and pattern is not only * then failif sindex >= len(source):for wildindex in xrange(pindex, len(pattern)):if pattern[wildindex] != wild_multi:result = Falsebreak# there's a string, but no patternelif pindex >= len(pattern):result = False# if next pattern is multi though, that's somethingelif pattern[pindex] == wild_multi:# for zero, simply check sindex, pindex + 1result = is_match(sindex, pindex + 1) # just for easier debug# if zero, than it's a match# otherwise we need to check multi# for that, if char is not a wild, then it has to match the source,result = result or is_match(sindex + 1, pindex)else:# either a regular char, or wild_singleresult = (( pattern[pindex] == wild_single or pattern[pindex] == source[sindex]) and is_match(sindex + 1, pindex + 1))seen[key] = resultreturn resultif (len(p) - p.count(wild_multi) > len(s)):return Falsereturn is_match(0, 0)

    轉載于:https://www.cnblogs.com/George1994/p/7182866.html

    總結

    以上是生活随笔為你收集整理的[LeetCode] Wildcard Matching 题解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 88久久精品无码一区二区毛片 | 69av一区二区三区 | 国产精品影院在线观看 | 中国三级视频 | 精品成人 | 欧美激情三级 | 在线免费观看中文字幕 | 免费操人视频 | 国产一区二区精品丝袜 | 黄色国产在线视频 | 久久大胆人体 | 欧美一级欧美三级在线观看 | 亚洲欧洲日本一区二区三区 | 99在线精品观看 | 亚洲成人第一区 | 草草影院在线播放 | 国产精品无码网站 | 美女网站黄页 | 视色在线 | 亚洲综合天堂 | 国模视频一区二区 | 国产高清精品软件丝瓜软件 | 精品久久综合 | 亚洲福利在线观看 | 国产麻豆成人精品av | 久久精品伦理 | 五月深爱 | 一级片a级片 | 日韩亚洲一区二区三区 | 日韩中文字幕在线观看视频 | 久久99日韩 | 欧美xxxⅹ性欧美大片 | 先锋影视av| 国模吧无码一区二区三区 | 国产对白videos麻豆高潮 | 又黄又爽一区二区三区 | 精品人伦一区二区三电影 | 色亚洲天堂 | 久久久久人妻一区二区三区 | 99久久久无码国产精品免费蜜柚 | 9l视频自拍蝌蚪9l视频成人 | 起碰在线 | 在线免费看黄色片 | 精品国产精品国产偷麻豆 | wwwwxxxxx日本 | 中文字幕欧美日韩 | 中文字幕精品一二三四五六七八 | 天天舔天天干 | 久久午夜精品人妻一区二区三区 | 中文字幕无线精品亚洲乱码一区 | 九九爱精品 | 欧美人妻少妇一区二区三区 | 欧美日韩一区二区三区在线电影 | 亚洲午夜无码av毛片久久 | 91九色国产ts另类人妖 | 一区二区不卡免费视频 | wwwxxx日韩 | 亚洲av日韩av在线观看 | 九色91| 黄色av大片 | 少妇被中出 | 日韩图色 | 麻豆影视网站 | 成人国产精品免费观看 | 狠狠操很很干 | 日韩激情综合 | 调教撅屁股啪调教打臀缝av | 四季av一区二区三区免费观看 | 五月婷婷综合激情 | 黄色裸体片 | 象人高潮调教丨vk | 有色影院| 久久久久久爱 | 欧美一区中文字幕 | 一级做a爱片久久毛片 | 国产在线观看不卡 | 日韩av手机在线播放 | av电影中文字幕 | 国产精品一品二品 | 国产成人精品一区二区色戒 | 亚洲黄a | 美女网站在线免费观看 | 台湾男男gay做爽爽的视频 | 国产亚洲91 | 国产在线自 | 亚洲欧美偷拍一区 | japanese国产 | 无码专区久久综合久中文字幕 | 天天槽 | 性生交大片免费看视频 | 国产乱码精品一区二区三区中文 | 精品国产日本 | 九九九久久久 | 日本一区二区欧美 | 欧美日韩高清在线 | 禁漫天堂下载18 | 国产欧美日韩一区二区三区 | 免费www xxx| 免费av导航 |