用動態(tài)規(guī)劃解決通配符匹配字符串問題

leetcode上這個題目出現(xiàn)了兩次春畔,基本都是要求答題者寫代碼完成 '*' 和 '?' 通配符的匹配优俘。
一下摘錄其中一題:

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

解決這道題可以用遞歸的方法坊罢,遞歸的思路代碼如下:
下列代碼中迈喉,首先判斷特殊情況(終止條件), 分兩種情況討論

  • 當(dāng)傳入的p為空時。
  • 當(dāng)傳入的s為空時览爵。
    然后考慮一般情況跪呈,也分兩種情況討論:
  • p 開頭為 '*'段磨,若開頭為星號,接下來有三種匹配方式:
    • p[0] 僅匹配單個字符 s[0]耗绿,p[1] ~ p[m] 匹配 s[1] ~ s[n]苹支,此時遞歸調(diào)用 isMatch(s.substr(1,s.size() - 1), p.substr(1,p.size() - 1))
    • p[0] 匹配字符串 s[0] ~ s[i],此時遞歸調(diào)用isMatch(s.substr(1,s.size() - 1), p.substr(0,p.size() ))
    • p[0]匹配空字符串误阻,此時遞歸調(diào)用isMatch(s.substr(0,s.size() ), p.substr(1,p.size() - 1))
  • p 開頭不為 '*'债蜜,如果p[0] 與 s[0]匹配,此時遞歸調(diào)用 isMatch(s.substr(1,s.size() - 1), p.substr(1,p.size() - 1))究反,否則匹配失敗寻定。
    將以上思路寫成代碼如下:
class Solution {
public:
    bool isMatch(string s, string p) {
        if(p.size() == 0) {
            if(s.size() == 0)
            return true;
            return false;
        }
        if(s.size() == 0) {
            if(p[0] == '*')
                return isMatch(s.substr(0,s.size()), p.substr(1,p.size() - 1));
            return false;
        }
        bool res;
        if(p[0] == '*') {
            res = isMatch(s.substr(1,s.size() - 1), p.substr(1,p.size() - 1)) || 
            isMatch(s.substr(1,s.size() - 1), p.substr(0,p.size())) || 
            isMatch(s.substr(0,s.size()), p.substr(1,p.size() - 1));
        }
        else {
            if(p[0] == s[0] || p[0] == '?')
                res = isMatch(s.substr(1,s.size() - 1), p.substr(1,p.size() - 1));
            else
                return false;
        }
        return res;
    }
};

但是,遞歸的思路解法速度不夠精耐,再leetcode上會超時狼速,那么就需要我們用動態(tài)規(guī)劃解決。
同樣的道理黍氮,根據(jù)上述遞歸的思路寫出遞推關(guān)系式

P[i][j] = P[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '?'), if p[j - 1] != '*';
P[i][j] = P[i][j - 1] || P[i - 1][j], if p[j - 1] == '*'.

依據(jù)上述關(guān)系唐含,可以寫出新的代碼,代碼如下:

class Solution {
public:
    bool isMatch(string s, string p) { 
        int m = s.length(), n = p.length();
        vector<bool> cur(m + 1, false); 
        cur[0] = true;
        for (int j = 1; j <= n; j++) {
            bool pre = cur[0]; // use the value before update
            cur[0] = cur[0] && p[j - 1] == '*'; 
            for (int i = 1; i <= m; i++) {
                bool temp = cur[i]; // record the value before update
                if (p[j - 1] != '*')
                    cur[i] = pre && (s[i - 1] == p[j - 1] || p[j - 1] == '?');
                else cur[i] = cur[i - 1] || cur[i];
                pre = temp;
            }
        }
        return cur[m]; 
    }
};
最后編輯于
?著作權(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)我...
    茶點故事閱讀 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
  • 正文 獨居荒郊野嶺守林人離奇死亡碳却,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年队秩,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昼浦。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡馍资,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出关噪,到底是詐尸還是另有隱情鸟蟹,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布色洞,位于F島的核電站戏锹,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏火诸。R本人自食惡果不足惜锦针,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望置蜀。 院中可真熱鬧奈搜,春花似錦、人聲如沸盯荤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽秋秤。三九已至宏粤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間灼卢,已是汗流浹背绍哎。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留鞋真,地道東北人崇堰。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像涩咖,于是被迫代替她去往敵國和親海诲。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,976評論 2 355

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