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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LeetCode精讲题 10正则表达式匹配(动态规划)

發(fā)布時間:2025/3/20 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LeetCode精讲题 10正则表达式匹配(动态规划) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

標(biāo)題

    • 題目描述
    • 遞歸(超時)
    • 動態(tài)規(guī)劃
    • 結(jié)語

題目描述

先點贊再觀看、帥哥靚女養(yǎng)成好習(xí)慣

10 正則表達式匹配

給你一個字符串 s 和一個字符規(guī)律 p,請你來實現(xiàn)一個支持 ‘.’ 和'*'的正則表達式匹配。
'.'匹配任意單個字符
'*'匹配零個或多個前面的那一個元素
所謂匹配,是要涵蓋 整個 字符串 s的,而不是部分字符串。

說明:

s 可能為空,且只包含從 a-z 的小寫字母。
p 可能為空,且只包含從 a-z 的小寫字母,以及字符 . 和 *。

示例 1:

輸入:
s = “aa”
p = "a"
輸出: false
解釋: “a” 無法匹配 “aa” 整個字符串。

示例 2:

輸入:
s = “aa”
p = "a*"
輸出: true
解釋: 因為 ‘*’ 代表可以匹配零個或多個前面的那一個元素, 在這里前面的元素就是 ‘a(chǎn)’。因此,字符串 “aa” 可被視為 ‘a(chǎn)’ 重復(fù)了一次。

示例 3:

輸入:
s = "ab"
p = ".*"
輸出: true
解釋: ".*" 表示可匹配零個或多個('*')任意字符('.')。

示例 4:

輸入:
s = “aab”
p = “cab”
輸出: true
解釋: 因為 ‘*’ 表示零個或多個,這里 ‘c’ 為 0 個, ‘a(chǎn)’ 被重復(fù)一次。因此可以匹配字符串 “aab”。

示例 5:

輸入:
s = “mississippi”
p = "mis*is*p*."
輸出: false

遞歸(超時)

這題剛開始見到,還以為遇到原題了,因為跟劍指offer的其中一題非常像,劍指offer第52題正則表達式,只不過那題給的兩個char類型的數(shù)組,當(dāng)時弱弱的用遞歸暴力過了。

然后一頓操作把上次遞歸的方法重寫過來,結(jié)果超時了……
但是還是把這種遞歸的思路講一下,遞歸主要進行匹配所有情況,主要是看當(dāng)前位置兩個串串能不能匹配。

需要考慮*情況可以匹配,因為*可以出現(xiàn)0次,1次多次。那么在遇到使用*的如果匹配了,可以通過遞歸實現(xiàn)下面三者方式

  • 它可以使用0次(相當(dāng)于跟字符串下一部分匹配 a*aa和aa這個第一個a*可以看成0次)
  • 也可以使用1次(在當(dāng)前往后移例如a*aa和aaa轉(zhuǎn)成aa和aa的匹配)
  • 也可以使用多次(例如a*和aaa轉(zhuǎn)成a*和aa的匹配)

同樣,如果遇到*不可以匹配,那么就使用0次就行了(b*aa和aa匹配轉(zhuǎn)換成aa和aa匹配)

如果下一個不是*,那就考慮是否相當(dāng)或者模式字符是否為.進行繼續(xù)匹配或者終止就可以,在考慮一些開始結(jié)束情況就可以了,一個大概的思維導(dǎo)圖可以看一下。

這部分實現(xiàn)的代碼如下:

public static boolean isMatch2(String s, String p) {//System.out.println(s+" "+p);if (p.length() == 0)// 模式串為false{if (s.length() == 0)return true;return false;} else if (s.length() == 0) {// 匹配串為0if (p.length() % 2 == 1)return false;else {for (int i = 1; i < p.length(); i += 2) {if (p.charAt(i) != '*')return false;}return true;}} else if (p.length() == 1) {//匹配串長度為1if((s.charAt(0) == p.charAt(0) || p.charAt(0) == '.')&&s.length()==1)//可以匹配return true;else {return false;}} else {// 兩個串串正常長度if(p.charAt(1)=='*')//下一個為*{if(s.charAt(0)==p.charAt(0)||p.charAt(0)=='.')//可以匹配 分別用0次 用若1次 用若干次{return isMatch(s.substring(1), p)||isMatch(s.substring(1), p.substring(2))||isMatch(s, p.substring(2));}else {//不匹配只能用0次return isMatch(s, p.substring(2));} }else {if(s.charAt(0)==p.charAt(0)||p.charAt(0)=='.')return isMatch(s.substring(1), p.substring(1));else {//完全失敗return false;}}}

很遺憾的超時了,不過在劍指offer是可以過的,主要遇到這種字符就會很麻煩:

isMatch("aaaaaaaaaaaaab", "a*a*a*a*a*a*a*a*a*a*c")

因為這里面匹配中的a*任意一個都可以使用若干次導(dǎo)致遞歸種類太多爆棧。嚶嚶嚶。

動態(tài)規(guī)劃

這題正確而大眾的解法當(dāng)然是動態(tài)規(guī)劃了,我們知道動態(tài)規(guī)劃重在動態(tài)的規(guī)劃方程。并且當(dāng)前結(jié)果是基于父結(jié)果的。這題剛好就可以使用動態(tài)規(guī)劃來解答。

我們使用我們聲明一個dp[][]=new boolean[匹配串長度+1][模式串長度+1] 的二位數(shù)組用來儲存結(jié)果, 其中dp[i][j]表示匹配串前i個和模式串前j個是否匹配。最終匹配串和模式串是否匹配就是返回dp[匹配串長度][模式串長度].

對于動態(tài)規(guī)劃的問題,我們一般會空余出0號位放在越界等特殊情況,所以我們聲明的二維數(shù)組大小長寬都大1,因為0號在dp[][]表示的是空串的結(jié)果而不是一號位置串的結(jié)果。然后我們在搞動態(tài)規(guī)劃題一般需要以下幾步:

  • 聲明dp數(shù)組,理解其含義
  • 聲明一些初始情況(一般為0)
  • 找正常情況動態(tài)方程式

這里的初始我們是dp[0][0]=true表示兩個空串可以匹配。

我們分析這個dp[i][j] 匹配串前i個,模式串前j個是否匹配.其實這個分析和之前遞歸還是有點相似的:

首先如果模式串pattern第j個如果是*,以下兩種情況任意一種匹配成功即可。

  • 如果dp[i][j-2]==true那么dp[i][j]肯定為true,因為可以把它看成一個空串。

  • 如果dp[i][j-2]不為true也不要緊,如果匹配串和模式串前一個字符可以匹配并且dp[i-1][j]為true,那么也可以匹配(a*和a )

如果模式串第j個不為*那么就是常規(guī)匹配了,如果當(dāng)前位置字符不匹配,那么就為false,如果當(dāng)前位置匹配且dp[i-1][j-1]==true那么dp[i][j]就為true:

當(dāng)然,以上所有考慮i-1的情況i不能等于0.

綜上分析得到dp方程為:

if(模式串當(dāng)前為*) dp[i][j]==dp[i][j-2]||(dp[i-1][j]&&兩串當(dāng)前字符可以匹配) else dp[i][j]=dp[i-1][j-1]&&兩串當(dāng)前字符可以匹配

具體實現(xiàn)需要注意下標(biāo)編號在字符串位置和dp下標(biāo)的含義,具體實現(xiàn)的代碼為:

public static boolean isMatch(String s, String p) {boolean dp[][]=new boolean[s.length()+1][p.length()+1];//默認(rèn)為falsedp[0][0]=true;for(int i=0;i<=s.length();i++){for(int j=1;j<=p.length();j++){if(p.charAt(j-1)=='*')//該位置為*{dp[i][j]=dp[i][j-2];//模式用了0次的看看是否能夠匹配,能匹配最好,不能匹配繼續(xù)if(!dp[i][j])//不能匹配{if(i==0) {continue;}else if(s.charAt(i-1)==p.charAt(j-2)||p.charAt(j-2)=='.')//可以匹配{dp[i][j]=dp[i-1][j];}}}else {//正常字符if(i==0){continue;}else if(s.charAt(i-1)==p.charAt(j-1)||p.charAt(j-1)=='.') {//這個位置可以匹配dp[i][j]=dp[i-1][j-1];}} }}return dp[s.length()][p.length()]; }

結(jié)語

今天又get一個動態(tài)規(guī)劃題,以前沒有用動態(tài)規(guī)劃的思維去想過,但是這題還是挺好的,至于一些其他的方法如果后面有時間可以繼續(xù)拓展。

原創(chuàng)不易,最后我請你幫兩件事幫忙一下:

  • star支持一下, 您的肯定是我在平臺創(chuàng)作的源源動力。

  • 微信搜索「bigsai」,關(guān)注我的公眾號,不僅免費送你電子書,我還會第一時間在公眾號分享知識技術(shù)。加我還可拉你進力扣打卡群一起打卡LeetCode。

  • 記得關(guān)注、咱們下次再見!

    《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

    總結(jié)

    以上是生活随笔為你收集整理的LeetCode精讲题 10正则表达式匹配(动态规划)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 国产九色 | 影音先锋黑人 | 蜜色av | 九七影院在线观看免费观看电视 | 久久久精品免费观看 | 精品免费久久 | 影音资源av| 成人网站免费观看入口 | 日韩精品激情 | 日本黄色大片免费看 | 精品成人av一区二区在线播放 | 丁香综合激情 | 草久免费视频 | 欧美日韩一区二区三区四区五区六区 | 亚洲精品乱码久久久久久蜜桃欧美 | 色在线综合 | 免费裸体美女网站 | 国内精品视频一区二区三区 | 丁香婷婷综合网 | 黄色三级免费观看 | 激情综合小说 | 夜夜撸av | 五月天色婷婷丁香 | 超碰97观看 | 插插插干干干 | 亚洲一区二区蜜桃 | 97av在线视频 | 深田咏美av在线 | 欧美日韩二区三区 | 欧美hdse| 色先锋在线 | 亚洲高清毛片一区二区 | 华人色| 在线观看a视频 | yy1111111| 日本高清视频一区二区三区 | 日韩欧美在线观看免费 | 欧美高清一区 | 无码人妻熟妇av又粗又大 | 欧美中文字幕一区二区三区 | 国产盗摄在线观看 | 欧美日韩免费一区 | 性活交片大全免费看 | 91av免费 | 国产亚洲综合在线 | 三上悠亚在线观看一区二区 | 免费人成在线观看网站 | 欧美久久一区二区三区 | 香蕉伊人网 | 99艹| 少妇无套内谢免费视频 | 91精品国自产 | 日韩色吧 | 国产成人在线播放视频 | 亚洲精品h | 久久久二区 | 亚洲精品网站在线播放gif | 黑人av | 亚洲精品亚洲人成人网 | 18岁成年人网站 | 国产精品二区一区 | 九色91popny蝌蚪新疆 | 三级欧美日韩 | 欧美性生交大片免费看 | 91蜜桃婷婷狠狠久久综合9色 | 男生操女生免费网站 | 中文字幕在线视频不卡 | 日本三级一区 | 黄色特一级 | 久久人妻少妇嫩草av蜜桃 | 久久观看最新视频 | 久久99国产精品 | 国产高清自拍视频 | 国产成人精品亚洲 | 午夜精品一区二区三区在线观看 | 中文字幕高清在线 | 国产大片av| a级大片免费看 | 青青青国产精品一区二区 | 亚洲五月网 | 成人小视频在线免费观看 | 紧身裙女教师三上悠亚红杏 | 婷婷色在线观看 | 20日本xxxxxxxxx46 欧美激情一级 | 9l视频自拍九色9l视频成人 | 亚洲三级在线看 | 成人精品影视 | 在线观看免费视频一区 | 四虎在线免费播放 | av在线第一页 | 亚洲 高清 成人 动漫 | 日韩视频一区二区在线观看 | 日韩三级国产精品 | 男女网站在线观看 | 水牛影视av一区二区免费 | 少妇又色又爽又黄的视频 | 精品乱码一区二区三区 | 亚洲欧美日韩国产精品 | 2020自拍偷拍 |