Brute Force: has '*' before ----- find last index of s and p when star found, s move forward
char s not reaches end -- > p reaches end
| no star ----- NOT MATCH
| same?
no / \ yes
is p '?" | s++ p++
no / \ yes
is p '*' | s++, p++
no / \ yes
has '*' before | skip all p star and record the index of s and p
no / \ yes
NOT MATCH find last index of s and p when star found
s move forward
class Solution { public boolean isMatch(String s, String p) { int prevS = 0; int prevP = 0; int currentS = 0; int currentP = 0; boolean star = false; while (currentS < s.length()) { if (currentP >= p.length()) { if (star) { currentS = ++prevS; currentP = prevP; } else { return false; } } if (s.charAt(currentS) != p.charAt(currentP)) { if (p.charAt(currentP) == '?') { currentS++; currentP++; } else if (p.charAt(currentP) == '*') { while (currentP < p.length() && p.charAt(currentP) == '*') { currentP++; } if (currentP == p.length()) { return true; } star = true; prevS = currentS; prevP = currentP; } else if (star) { currentS = ++prevS; currentP = prevP; } else { return false; } } else { currentS++; currentP++; } } while (currentP < p.length() && p.charAt(currentP) == '*') { currentP++; } return currentP == p.length(); } }
DP:
For dp[i][j] = dp[i + 1][j] || dp[i][j + 1] means either there is a point k that s(k , end) matches p(j + 1, end) when k > i or * matches 0 char here. So s(i , end) matches p(j + 1, end)
class Solution { public boolean isMatch(String s, String p) { boolean[][] dp = new boolean[s.length() + 1][p.length() + 1]; dp[s.length()][p.length()] = true; for (int i = p.length() - 1; i >= 0; i--) { if (p.charAt(i) != '*') { break; } dp[s.length()][i] = true; } for (int i = s.length() - 1; i >= 0; i--) { for (int j = p.length() - 1; j >= 0; j--) { if (p.charAt(j) == '?' || p.charAt(j) == s.charAt(i)) { dp[i][j] = dp[i + 1][j + 1]; } else if (p.charAt(j) == '*') { dp[i][j] = dp[i + 1][j] || dp[i][j + 1]; } else { dp[i][j] = false; } } } return dp[0][0]; } }