leetcode 44. Wildcard Matching

這裏寫圖片描述

  這是我在leetcode上做的第一道hard難度的題,最終還是看了討論區的做法才做出來。這題的意思是,給兩個字符串s和p,判斷它們是否是完全匹配,其中p中的*可以代表任意長度的任意字符,?代表某個字符。完全匹配返回true,否則返回false。這題乍看很簡單(最終答案也不長),但其中有許多需要考慮的問題,稍有不慎一些測試樣例就過不去了。在不斷碰壁之後,我發現這些問題都是出在*這個字符上,或者更直白一點,就是*應該代表s中哪段字符才合適。

 先說解題思路,可以先用兩個變量(i和j)存儲s和p中要檢查的字符的位置,將s中的字符和p中的字符進行一一比較,相同或者p中字符是?則i++,j++。如果不是,情況就分爲三種:(1).p[j]是*;(2).p[j]越界或者p[j]未越界但不爲*,但是字符串p的前面位置出現了*;(3).p[j]不是*並且前面也沒有*,那麼s和p不能完全匹配。

 由此可見,三種情況之中,第一種和第二種較爲棘手。考慮到*是空串的情況,遇到情況(1)時,i不需要變化,但需要j++(解決”a”和”*?*”的情況)。爲了不讓p中的*代表的字符串過短,我們需要記錄最近的一個*出現的位置(starIndex),在每次遇到第一種情況時都進行記錄,以便我們在遇到第二種情況的時候,可以通過這個記錄,將檢查的p中的字符位置返回到*的後一個位置,繼續進行匹配。這樣就可以解決一些如”abefcdgiescdfimde”和”ab*cd?i*de”的匹配。而另外還有個問題,比如”aa”和”*”,匹配完s第1個a之後,p中字符位置就越界了,但是i並沒有增加,則j會變爲1,i依舊不會變化,這樣就形成了死循環。因此我們還需要記錄最近的一次和*匹配的s中字符的位置(match),在進行情況(3)處理的時候將i賦值爲match+1,然後增加match。

 實現代碼如下

class Solution {
public:
    bool isMatch(string s, string p) {
        int j = 0;
        int i = 0;
        int starIndex = -1;
        int match; 
        while (i < s.size()) {
            if((j < p.size())&&((s[i] == p[j])||(p[j] == '?'))) {
                i++;
                j++;
            } else {
                if ((j < p.size())&&(p[j] == '*')) {
                    starIndex = j;
                    match = i;
                    j++;
                } else {
                    if (starIndex != -1) {
                        j = starIndex + 1;
                        match++;
                        i = match;
                    } else return false;
                }
            }
        }
        while ((j < p.size())&&(p[j] == '*')) {
            j++;
        }
        return (j == p.size());
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章