44. 通配符匹配
  1. 通配符匹配

难度困难470

给定一个字符串 (s) 和一个字符模式 § ,实现一个支持 ‘?’ 和 ‘*’ 的通配符匹配。

'?' 可以匹配任何单个字符。
'*' 可以匹配任意字符串(包括空字符串)。

两个字符串完全匹配才算匹配成功。

说明:

  • s 可能为空,且只包含从 a-z 的小写字母。
  • p 可能为空,且只包含从 a-z 的小写字母,以及字符 ? 和 *。

示例 1:

输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。
	//dp 通过创建一个二维的数组,从左上角依次通过前一个的状态 来确定当前的状态是否可以匹配到。
    //1. a.如果当前s.charAt(j-1) == p.charAt(i-1) 说明两者相等 dp[i][j] = dp[i-1][j-1]
    //   b.如果当前p.charAt(i-1) == '?' ? 表示可以匹配单个字符 dp[i][j] = dp[i-1][j-1]
    //2. 如果遇到  '*'  a. '*' 匹配了当前字符  dp[i][j] = dp[i][j-1]
    //                 b. '*' 没有匹配当前字符 dp[i][j] = dp[i-1][j]
    // 时间复杂度为O(M*N)  空间复杂度为O(M*N)
 		//dp 通过创建一个二维的数组,从左上角依次通过前一个的状态 来确定当前的状态是否可以匹配到。
        //1. a.如果当前s.charAt(j-1) == p.charAt(i-1) 说明两者相等 dp[i][j] = dp[i-1][j-1]
        //   b.如果当前p.charAt(i-1) == '?' ? 表示可以匹配单个字符 dp[i][j] = dp[i-1][j-1]
        //2. 如果遇到  '*'  a. '*' 匹配了当前字符  dp[i][j] = dp[i][j-1]
        //                 b. '*' 没有匹配当前字符 dp[i][j] = dp[i-1][j]
        // 时间复杂度为O(M*N)  空间复杂度为O(M*N)
        public boolean isMatch(String s, String p) {
            int len1 = p.length(), len2 = s.length();
            //行p 列s
            boolean [][] dp = new boolean [len1+1][len2+1];
            dp[0][0] = true;
    
            for(int i=1;i<=len1;i++){
                if(p.charAt(i-1) != '*'){
                    break;
                }
                dp[i][0] = true;
            }
    
            for(int i=1;i<=len1;i++){
                for(int j=1;j<=len2;j++){
                    if((s.charAt(j-1) == p.charAt(i-1)) || p.charAt(i-1) == '?'){
                        dp[i][j] = dp[i-1][j-1];
                    }else if(p.charAt(i-1) == '*'){
                        //dp[i-1][j] 上一行没有匹配字符 dp[i][j-1] 匹配了当前字符
                        dp[i][j] = dp[i-1][j] | dp[i][j-1];
                    } 
                }
            }
            return dp[len1][len2];
        }