1. 程式人生 > >leetcode 44. 萬用字元匹配

leetcode 44. 萬用字元匹配

給定一個字串 (s) 和一個字元模式 (p) ,實現一個支援 '?' 和 '*' 的萬用字元匹配。

'?' 可以匹配任何單個字元。
'*' 可以匹配任意字串(包括空字串)。

兩個字串完全匹配才算匹配成功。

說明:

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

示例 1:

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

示例 2:

輸入:
s = "aa"
p = "*"
輸出: true
解釋: '*' 可以匹配任意字串。

示例 3:

輸入:
s = "cb" p = "?a" 輸出: false 解釋: '?' 可以匹配 'c', 但第二個 'a' 無法匹配 'b'。

示例 4:

輸入:
s = "adceb"
p = "*a*b"
輸出: true
解釋: 第一個 '*' 可以匹配空字串, 第二個 '*' 可以匹配字串 "dce".

示例 5:

輸入:
s = "acdcb"
p = "a*c?b"
輸入: false

思路

  1. 一開始想窮舉,發現由於*可以任意匹配,失敗
  2. 看了資料,發現居然使用dp做
  3. 在此補充範例:
  4. s = abc p = a*c
  5. dp[1][1] = s[0]==p[0] ->1
  6. dp[1][2] = s[0]==p[0-1] -> 1
  7. dp[1][3] = s[0]==p[0-2] ->a==a*c->0

code

class Solution {
public:
    bool isMatch(string s, string p) {
        //dp[i][j]表示s的前i個字元和p的前j個字元的匹配情況
        int m=s.size(),n=p.size();
        vector<vector<int>> dp(m+1,vector<int>(n+1,0));
        dp[0][0]=1;
        for (int j = 1; j <= p.size(); ++j){//初始化
            if (p[j-1] == '*') dp[0][j] = dp[0][j-1];
        }
        for(int i=1;i<=m;++i){
            for(int j=1;j<=n;++j){
                if(p[j-1]!='*'){
                    if(s[i-1]==p[j-1] || p[j-1]=='?')
                        dp[i][j] = dp[i-1][j-1];
                }else{
                    dp[i][j] = dp[i-1][j] ||dp[i][j-1] || dp[i-1][j-1];
                }
            }
        }
        return dp[m][n];
    }
};