力扣_字符串3—通配符匹配

题目

给你一个输入字符串 s s s 和一个字符模式 p p p ,请你实现一个支持 ? ? ? ∗ * 匹配规则的通配符匹配:

  • ? ? ? 可以匹配任何单个字符。
  • ∗ * 可以匹配任意字符序列(包括空字符序列)。
    判定匹配成功的充要条件是:字符模式必须能够 完全匹配 输入字符串(而不是部分匹配)。

方法

动态规划

  • s s s 长度为 n 1 n_1 n1, p p p 长度为 n 2 n_2 n2
  • 构造 d p n 1 + 1 , n 2 + 1 dp_{n_1+1, n_2+1} dpn1+1,n2+1 数组
    • d p [ i ] [ j ] = = 1 dp[i][j] == 1 dp[i][j]==1,则表示 s [ 0 , i − 1 ] s[0, i-1] s[0,i1] 可以与 p [ 0 , j − 1 ] p[0,j-1] p[0,j1] 匹配
  • 转移
    • p [ j − 1 ] = = ? p[j-1] == ? p[j1]==?,则 d p [ i ] [ j ] = d p [ i − 1 ] [ j − 1 ] dp[i][j] = dp[i-1][j-1] dp[i][j]=dp[i1][j1] (因为 ? ? ? 可以和任意单个字符匹配)
    • p [ j − 1 ] = = ∗ p[j-1] == * p[j1]==,则,
      • ∗ * 匹配 0 0 0 个字符,则 d p [ i ] [ j ] = d p [ i ] [ j − 1 ] dp[i][j] = dp[i][j-1] dp[i][j]=dp[i][j1] p [ 0 , j − 1 ] p[0,j-1] p[0,j1] s [ 0 , i − 1 ] s[0,i-1] s[0,i1] 是否匹配取决于 p [ 0 , j − 2 ] p[0,j-2] p[0,j2] s [ 0 , i − 1 ] s[0,i-1] s[0,i1] 是否匹配,因为此时 p [ j − 1 ] p[j-1] p[j1] 不参与匹配)
      • ∗ * 匹配 1 1 1 个字符,则 d p [ i ] [ j ] = d p [ i − 1 ] [ j ] dp[i][j] = dp[i-1][j] dp[i][j]=dp[i1][j] p [ 0 , j − 1 ] p[0,j-1] p[0,j1] s [ 0 , i − 1 ] s[0,i-1] s[0,i1] 是否匹配取决于 p [ 0 , j − 1 ] p[0,j-1] p[0,j1] s [ 0 , i − 2 ] s[0,i-2] s[0,i2] 是否匹配,因为此时 p [ j − 1 ] p[j-1] p[j1] 匹配了 s [ i − 1 ] s[i-1] s[i1],还要继续看 p [ j − 1 ] p[j-1] p[j1] 是否匹配 s [ i − 2 ] s[i-2] s[i2]
      • 综上 d p [ i ] [ j ] = d p [ i − 1 ] [ j ] dp[i][j] = dp[i-1][j] dp[i][j]=dp[i1][j] d p [ i ] [ j − 1 ] dp[i][j-1] dp[i][j1]
    • p [ j − 1 ] p[j-1] p[j1] 为字母,
      • s [ i − 1 ] = = p [ j − 1 ] s[i-1] == p[j-1] s[i1]==p[j1],则 d p [ i ] [ j ] = d p [ i − 1 ] [ j − 1 ] dp[i][j] = dp[i-1][j-1] dp[i][j]=dp[i1][j1],否则为0

代码

class Solution {
public:
    bool isMatch(string s, string p) {
        int n1 = s.size();
        int n2 = p.size();
        vector<vector<int>> dp(n1+1, vector<int>(n2+1));
        dp[0][0] = 1;
        for (int i = 1; i <= n2; ++i) {
            if (p[i - 1] == '*') {
                dp[0][i] = true;
            }
            else {
                break;
            }
        }
        for(int i = 1; i <= n1; i++){
            for(int j = 1; j <= n2; j++){
                if(p[j-1] == '?'){
                    dp[i][j] = dp[i-1][j-1];
                }
                else if(p[j-1] == '*'){
                    dp[i][j] = dp[i][j - 1] | dp[i - 1][j];
                }
                else{
                    if(p[j-1] == s[i-1]){
                        dp[i][j] = dp[i-1][j-1];
                    }
                    else{
                        dp[i][j] = 0;
                    }
                }
            }
        }
        return dp[n1][n2];
    }
};

你可能感兴趣的:(leetcode,算法,职场和发展)