class Solution {
public boolean isMatch(String s, String p) {
if (s == null || p == null) {
return false;
}
boolean[][] dp = new boolean[s.length() + 1][p.length() + 1];
dp[0][0] = true;
// This for loop deals with pattern like 'a*b*'
for (int i = 1; i < dp[0].length; i++) {
if (p.charAt(i - 1) == '*') {
dp[0][i] = dp[0][i - 2];
}
}
for (int i = 1; i < dp.length; i++) {
for (int j = 1; j < dp[0].length; j++) {
if (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '.') {
dp[i][j] = dp[i - 1][j - 1]; // match, so whether regex match depends on status without these two
}
else if (p.charAt(j - 1) == '*') { // when meeting '*', dp thinking kicks in
// dp[i][j - 2] checks if 0 occurence of last character in pattern could result in regex match.
// p.charAt(j - 2) == s.charAt(i - 1) checks if character before '*' in p matches current character in s
// or if character before '*' is a '.'. If either of them is true, we can eliminate character at i
// position and depends on status at i - 1 position.
dp[i][j] = dp[i][j - 2];
if (p.charAt(j - 2) == s.charAt(i - 1) || p.charAt(j - 2) == '.') {
dp[i][j] = dp[i][j] || dp[i - 1][j];
}
}
else {
dp[i][j] = false;
}
}
}
return dp[dp.length - 1][dp[0].length - 1];
}
}
- time O(m * n) space O(m * n)
- The idea is to use dynammic programming to solve this problem. Notice that '.*' can represent 0 to many of any characters, so
'abxsdady' would match with 'a.*y'.
- There are couple of cases that we need to consider for this problem.
1). Match.
2). Meeting *
i). check whether 0 occurence of character before * will result in regex matching
ii). check whether character before * combined with * could result in regex matching. To achieve this, we check if
character before * match with current character in s or if character before '*' is a '.'.
3). If not conditions above, set the current matching to false.