[Leetcode 44]通配符匹配Wildcard Matching

时间:2022-05-26 15:15:44

【题目

匹配通配符*,?,DP动态规划,重点是*的两种情况

想象成两个S、P长度的字符串,P匹配S。

S中不会出现通配符。

【条件】

(1)P=null,S=null,TRUE

(2)P=null,S!=null,P必然无法匹配S,FALSE。

(3)P[i]=“*” 的TRUE/FALSE状态等价于P[i-1]

(4)考虑*两种情况,ab, ab*(*=null)、abcd, ab*(*=cd)

【参考】

The most confusing part for me is how to deal with '*'. At first I couldn't figure out why the condition would be (dp[i-1][j] == true || dp[i][j-1] == true). Hope detailed DP description below helps!

  • dp[i][j]: true if the first i char in String s matches the first j chars in String p
  • Base case:
    • origin: dp[0][0]: they do match, so dp[0][0] = true
    • first row: dp[0][j]: except for String p starts with *, otherwise all false
    • first col: dp[i][0]: can't match when p is empty. All false.
  • Recursion:
    • Iterate through every dp[i][j]
    • dp[i][j] = true:
      • if (s[ith] == p[jth] || p[jth] == '?') && dp[i-1][j-1] == true
      • elif p[jth] == '*' && (dp[i-1][j] == true || dp[i][j-1] == true) 
        -for dp[i-1][j], means that * acts like an empty sequence. 
        eg: ab, ab*
        -for dp[i][j-1], means that * acts like any sequences
        eg: abcd, ab*
  • Start from 0 to len
  • Output put should be dp[s.len][p.len], referring to the whole s matches the whole p

Be careful about the difference of index i,j in String (0 to len-1) and the index i, j in dp (0 to len)!


Below is my AC code in Java:

public boolean isMatch(String s, String p) {
if(s == null || p == null) return false;
int sLen = s.length();
int pLen = p.length();
boolean[][] dp = new boolean[sLen + 1][pLen + 1]; // Base cases:
dp[0][0] = true;
for(int i = 1; i <= sLen; i++){
dp[i][0] = false;
}
for(int j = 1; j <= pLen; j++){
if(p.charAt(j-1) == '*'){
dp[0][j] = dp[0][j-1];
}
} // Recursion:
for(int i = 1; i <= sLen; i++){
for(int j = 1; j <= pLen; j++){
if((s.charAt(i-1) == p.charAt(j-1) || p.charAt(j-1) == '?') && dp[i-1][j-1])
dp[i][j] = true;
else if (p.charAt(j-1) == '*' && (dp[i-1][j] || dp[i][j-1]))
dp[i][j] = true;
}
}
return dp[sLen][pLen];
}