This Solution use 2D DP. beat 90% solutions, very simple.
Here are some conditions to figure out, then the logic can be very straightforward.
1, If p.charAt(j) == s.charAt(i) : dp[i][j] = dp[i-1][j-1];
2, If p.charAt(j) == '.' : dp[i][j] = dp[i-1][j-1];
3, If p.charAt(j) == '*':
here are two sub conditions:
1 if p.charAt(j-1) != s.charAt(i) : dp[i][j] = dp[i][j-2] //in this case, a* only counts as empty
2 if p.charAt(i-1) == s.charAt(i) or p.charAt(i-1) == '.':
dp[i][j] = dp[i-1][j] //in this case, a* counts as multiple a
or dp[i][j] = dp[i][j-1] // in this case, a* counts as single a
or dp[i][j] = dp[i][j-2] // in this case, a* counts as empty
class Solution {
public boolean isMatch(String s, String p) {
if (s == null && p == null) return true;
int n = s.length(), m = p.length();
boolean[][] dp = new boolean[n + 1][m + 1];
dp[0][0] = true;
for (int j = 1; j <= m; j++){
if (p.charAt(j - 1) == '*'){
dp[0][j] = dp[0][j - 1] || (j >= 2 && dp[0][j - 2]);
}
}
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++){
if (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '.'){
dp[i][j] = dp[i - 1][j - 1];
}
if (p.charAt(j - 1) == '*'){
if (s.charAt(i - 1) != p.charAt(j - 2) && p.charAt(j - 2) != '.'){
dp[i][j] = dp[i][j - 2];
}
else{
// multiple: dp[i - 1][j]
// single: dp[i][j - 1]
// none: dp[i][j - 2]
dp[i][j] = dp[i - 1][j] || dp[i][j - 1] || dp[i][j - 2];
}
}
}
}
return dp[n][m];
}
}