10. Regular Expression Matching

Hard
fb tag
https://www.youtube.com/watch?v=DqhPJ8MzDKM
此題簡稱為"p中找s", 用dp做。
這道題一開始我naive地覺得如果p.length() < s.length()則一定return false. 然而*的含義是零個(gè)或多個(gè)它前面的字符,所以完全可能p的長度沒有s長触机,因?yàn)?code>*可以控制字符數(shù). 這里我們assume *只可能出現(xiàn)在charAt(i) i >= 1.
dp[i][j]表示s.substring(0, i)跟p.substring(0, j)是不是匹配畜普,也就是s里面前i個(gè)字符跟p里面前j個(gè)字符是否匹配砸脊。
首先dp[0][0] = true,因?yàn)閮蓚€(gè)空字符是相匹配的涡匀。
至于我們?yōu)槭裁匆獑为?dú)把dp[0][i]單獨(dú)拿出來初始化拴事,是因?yàn)楹竺娈?dāng)i >= 1, j >= 1的時(shí)候蒋伦,我們要用到dp[i-1][j-1]這樣的前面的狀態(tài)弓摘,而dp[0][something]帶入到這里的話就會(huì)越界。同樣很intuitive的我們可以知道dp[something][0] = false, 因?yàn)樵诳兆址锩婺阍趺凑乙舱也坏絪. 所以就不單獨(dú)initialize了痕届。

那么中間的部分韧献,我們分兩種大類討論。

  • 斜線(對角線)遞推
  • 直線(左到右研叫,上到下)遞推

斜線遞推是說當(dāng)p.charAt(j-1) == s.charAt(i-1)時(shí)锤窑,或者p.charAt(j-1) == '.'時(shí),我們的dp[i][j] = dp[i-1][j-1], 就相當(dāng)于一條斜線從左上角i-1,j-1穿到了i,j.
直線遞推是當(dāng)p.charAt(j-1) == *時(shí)嚷炉,我們可以選擇讓它代表前面的字符一共0個(gè)或者多個(gè)渊啰。當(dāng)它代表前面的字符零個(gè)的時(shí)候,我們就相當(dāng)于把p刪掉了后面兩個(gè)字符,所以dp[i][j] = dp[i][j-2]. 當(dāng)它代表前面的字符有多個(gè)的時(shí)候绘证,我們要考慮一種特殊情況隧膏,就是當(dāng)p.charAt(j-2) == s.charAt(i-1), 也就是p倒數(shù)第二個(gè)字符(倒數(shù)第一個(gè)是*)等于s的倒數(shù)第一個(gè)字符,或者p的倒數(shù)第二個(gè)字符干脆就是任意字符.,這種情況dp[i][j] = dp[i-1][j], 也就是如果這時(shí)候s除去最后一個(gè)字符剩下的部分跟p匹配的話嚷那,因?yàn)?code>*可以讓p繼續(xù)添加一個(gè)當(dāng)前最后的字符胞枕,而這個(gè)字符又剛好等于s的最后一個(gè)字符,所以他們會(huì)繼續(xù)匹配魏宽,因此此時(shí)dp[i][j] = dp[i-1][j]. 比如p = ab*, s = abb, 這時(shí)候就可以得到dp[3][3] = dp[2][3]. 但是這種情況我們不能直接就不考慮 *代表零個(gè)了腐泻,而是只要其中一種匹配就return true.
這個(gè)test case可以測出來必須兩個(gè)都寫:
"aaa"
"ab*a*c*a"

class Solution {
    public boolean isMatch(String s, String p) {
        if (p == null || s == null){
            return false;
        }   
        //"aaa"
        //".*"
        boolean[][] dp = new boolean[s.length() + 1][p.length() + 1];
        //dp[i][j]: s.substring(0, i) matches with p.substring(0, j); i,j means number of characters,not index.
        dp[0][0] = true; //"" matches ""
        
        for(int i = 1; i < p.length() + 1; i++){
            if (p.charAt(i-1) == '*'){
                dp[0][i] = dp[0][i-2];
            }
        }
        
        for (int i = 1; i < s.length() + 1; i++){
            for (int j = 1; j < p.length() + 1; j++){
                if (s.charAt(i-1) == p.charAt(j-1) || p.charAt(j-1) == '.'){
                    dp[i][j] = dp[i-1][j-1];
                } else if (p.charAt(j-1) == '*'){
                    //"*" could means zero or multiple
                    if (p.charAt(j-2) == s.charAt(i-1) || p.charAt(j-2) == '.'){
                        dp[i][j] = dp[i-1][j] || dp[i][j-2];
                    } else {
                        dp[i][j] = dp[i][j-2];
                    }
                }                
            }
        }
        return dp[s.length()][p.length()];
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市队询,隨后出現(xiàn)的幾起案子派桩,更是在濱河造成了極大的恐慌,老刑警劉巖娘摔,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窄坦,死亡現(xiàn)場離奇詭異,居然都是意外死亡凳寺,警方通過查閱死者的電腦和手機(jī)鸭津,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來肠缨,“玉大人逆趋,你說我怎么就攤上這事∩罐龋” “怎么了闻书?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長脑慧。 經(jīng)常有香客問我魄眉,道長,這世上最難降的妖魔是什么闷袒? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任坑律,我火速辦了婚禮,結(jié)果婚禮上囊骤,老公的妹妹穿的比我還像新娘晃择。我一直安慰自己,他們只是感情好也物,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布宫屠。 她就那樣靜靜地躺著,像睡著了一般滑蚯。 火紅的嫁衣襯著肌膚如雪浪蹂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天,我揣著相機(jī)與錄音乌逐,去河邊找鬼竭讳。 笑死,一個(gè)胖子當(dāng)著我的面吹牛浙踢,可吹牛的內(nèi)容都是我干的绢慢。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼洛波,長吁一口氣:“原來是場噩夢啊……” “哼胰舆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蹬挤,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤缚窿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后焰扳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體倦零,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年吨悍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了扫茅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,577評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡育瓜,死狀恐怖葫隙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情躏仇,我是刑警寧澤恋脚,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站焰手,受9級特大地震影響糟描,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜书妻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一蚓挤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧驻子,春花似錦、人聲如沸估灿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽馅袁。三九已至域慷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背犹褒。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工抵窒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人叠骑。 一個(gè)月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓李皇,卻偏偏與公主長得像,于是被迫代替她去往敵國和親宙枷。 傳聞我的和親對象是個(gè)殘疾皇子掉房,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容