Leetcode 刷題指北 10.Regular Expression Matching


Implement regular expression matching with support for '.' and '*'.

'.' Matches any single character.
'*' Matches zero or more of the preceding element.

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") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "a*") → true
isMatch("aa", ".*") → true
isMatch("ab", ".*") → true
isMatch("aab", "c*a*b") → true

解題思路

時間復(fù)雜度: O(nm)
字符串比較一般都可以先想到動態(tài)規(guī)劃哮肚,此題只需要計算一個n*m的矩陣即可求解卤档,所以復(fù)雜度是O(nm)。(nm分別是ps的長度)
1姨拥、n*m的矩陣用于記錄正則式p從開頭到下標(biāo)i結(jié)束的子串與目標(biāo)字符串s從開頭到下標(biāo)i結(jié)束的子串的比較結(jié)果鱼炒。
2叶撒、基于下標(biāo)小的元素以及比對字符可以計算出下標(biāo)大的元素,從而填滿整個矩陣贪嫂。
3寺庄、矩陣計算完畢后,返回對應(yīng)元素即可力崇。
4斗塘、矩陣的元素是怎么計算的,用一個例子來說明亮靴,如下圖:

圖1. 示例

  1. 橫向是目標(biāo)字符串s馍盟,縱向是正則式p。定義該矩陣為C
  2. 初始化第一行茧吊。當(dāng)sp均為空時贞岭,匹配正確八毯,所以C[0][0] = 1。當(dāng)p為空串而s不為空時瞄桨,一定匹配錯誤话速,所以第一行其他列均賦值為0。
  3. 初始化第一列芯侥。第一列表示s為空串泊交,這種情況只有當(dāng)p中出現(xiàn)*時匹配結(jié)果可能為真,如圖中第一列標(biāo)紅的位置柱查。當(dāng)p中出現(xiàn)*時廓俭,該元素同一列上前兩個元素任意一個為真,它就為真唉工。具體原因在4.中解釋研乒,所以C[2][0] = C[0][0]
  4. 計算其他元素淋硝。有如下情況:
p[i] == p[j] || p[i] == '.': // 該元素對應(yīng)子串匹配正確 
        C[i + 1][j + 1] = C[i][j] 
p[i] == '*': // x*代表字符x出現(xiàn) 0 次雹熬、1 次、1次以上奖地。
        C[i + 1][j + 1] = C[i - 1][j + 1] // x*代表x出現(xiàn)0次時橄唬,匹配結(jié)果等同于“x*”沒出現(xiàn)過
                                    //即當(dāng)前 p 的子串向前跳兩個字符與當(dāng)前 s 的子串的匹配結(jié)果

        C[i + 1][j + 1] = C[i][j + 1] // x*代表x出現(xiàn)1次時赋焕,匹配結(jié)果等同于沒有該星號参歹,
                                      // 以前一個字符為結(jié)尾的 p 的子串與 s 的子串的匹配結(jié)果。

        C[i + 1][j + 1] = C[i + 1][j] // x*代表x出現(xiàn)1次以上時隆判,只要當(dāng)前 s 的子串的結(jié)尾字
                                    // 符與 p 的子串的 * 的前一個字符(別忘了'.'的情況)能匹配上犬庇,
                               // 當(dāng)前匹配結(jié)果就等同于以 * 前一位字符結(jié)尾的 p 子串與 s 子串的匹配結(jié)果。

簡單來說侨嘀,p[i] == '*'的情況只需要考慮如圖中的反向“L”區(qū)域臭挽,其他位置出現(xiàn) 1 則當(dāng)前位置為 1 ,否則為 0 咬腕。

解題源碼

#include<iostream>
#include<string>
#include<vector>
using namespace std;

class Solution {
public:
    bool isMatch(string s, string p) {
        int m = s.length(), n = p.length();
        vector<vector<bool>> check(n + 1, vector<bool>(m + 1, false));// 用 false 初始化所有元素
        
        // 初始化第一個元素欢峰,其他第一行元素已經(jīng)初始化為 false 了
        check[0][0] = true;
        // 初始化第一列
        for (int i = 0; i <n; ++i) {
            if (p[i] == '*') {
                check[i + 1][0] = i >= 1 && check[i - 1][0] || i >= 0 && check[i][0];
            }
        }
        // 計算其他元素
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                if (p[i] == '.' || p[i] == s[j]) check[i + 1][j + 1] = check[i][j];
                else if (p[i] == '*') {
                    check[i + 1][j + 1] = check[i - 1][j + 1] || check[i][j + 1] || (p[i - 1] == s[j] || p[i - 1] == '.') && check[i + 1][j];
                }
            }
        }
        // 返回結(jié)果
        return check[n][m];
    }
};

參考

Discuss

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市涨共,隨后出現(xiàn)的幾起案子纽帖,更是在濱河造成了極大的恐慌,老刑警劉巖举反,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件懊直,死亡現(xiàn)場離奇詭異,居然都是意外死亡火鼻,警方通過查閱死者的電腦和手機(jī)室囊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進(jìn)店門雕崩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人融撞,你說我怎么就攤上這事盼铁。” “怎么了尝偎?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵捉貌,是天一觀的道長。 經(jīng)常有香客問我冬念,道長趁窃,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任急前,我火速辦了婚禮醒陆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘裆针。我一直安慰自己刨摩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布世吨。 她就那樣靜靜地躺著澡刹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪耘婚。 梳的紋絲不亂的頭發(fā)上罢浇,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天,我揣著相機(jī)與錄音沐祷,去河邊找鬼嚷闭。 笑死,一個胖子當(dāng)著我的面吹牛赖临,可吹牛的內(nèi)容都是我干的胞锰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼兢榨,長吁一口氣:“原來是場噩夢啊……” “哼嗅榕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起吵聪,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤凌那,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后暖璧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體案怯,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年澎办,在試婚紗的時候發(fā)現(xiàn)自己被綠了嘲碱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片金砍。...
    茶點(diǎn)故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖麦锯,靈堂內(nèi)的尸體忽然破棺而出恕稠,到底是詐尸還是另有隱情,我是刑警寧澤扶欣,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布鹅巍,位于F島的核電站,受9級特大地震影響料祠,放射性物質(zhì)發(fā)生泄漏骆捧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一髓绽、第九天 我趴在偏房一處隱蔽的房頂上張望敛苇。 院中可真熱鬧,春花似錦顺呕、人聲如沸枫攀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽来涨。三九已至,卻和暖如春启盛,著一層夾襖步出監(jiān)牢的瞬間蹦掐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工驰徊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留笤闯,地道東北人堕阔。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓棍厂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親超陆。 傳聞我的和親對象是個殘疾皇子牺弹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評論 2 355

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