[LeetCode 44] Wildcard Matching
Implement wildcard pattern matching with support for '?'
and '*'
.
'?'
Matches any single character.'*'
Matches any sequence of characters (including the empty sequence).
The matching should cover the entire input string (not partial).
For str[0 ~ i] and pattern[0 ~ j], we have the following cases.
1. str[i] == pattern[j] or pattern[j] == '?' : the problem is reduced to check if str[0 ~ i - 1] and pattern[0 ~ j - 1] match.
2. pattern[j] == '*',
if we use this * to match str[i], reduced to str[0 ~ i - 1] and pattern[0 ~ j];
if we do not use this * to match str[i], reduced to str[0 ~ i] and pattern[0 ~ j - 1];
3. all other cases indicate str[0 ~ i] and pattern[0 ~ j] do not match.
Based on the above analysis, we can solve it recursively, or better use dynamic programming to solve it.
Solution 1. Recursion
1 public class WildcardMatching {
2 public boolean isMatchRecursion(String str, String pattern) {
3 if(str == null || pattern == null) {
4 return false;
5 }
6 String newPattern = pattern.replaceAll("(\\*){2,}", "*");
7 return matchHelper(str, str.length() - 1, newPattern, newPattern.length() - 1);
8 }
9 private boolean matchHelper(String str, int idx1, String pattern, int idx2) {
10 if((idx1 < 0 && idx2 < 0) || (idx1 < 0 && idx2 == 0 && pattern.charAt(idx2) == '*')) {
11 return true;
12 }
13 else if(idx1 < 0 && idx2 >= 0 || idx1 >= 0 && idx2 < 0) {
14 return false;
15 }
16 if(pattern.charAt(idx2) == '?' || str.charAt(idx1) == pattern.charAt(idx2)) {
17 return matchHelper(str, idx1 - 1, pattern, idx2 - 1);
18 }
19 else if(pattern.charAt(idx2) == '*') {
20 return matchHelper(str, idx1, pattern, idx2 - 1) || matchHelper(str, idx1 - 1, pattern, idx2);
21 }
22 return false;
23 }
24 private String removeRedundantStars(String s) {
25 char[] chars = s.toCharArray();
26 int j = chars.length - 1, i = chars.length - 1;
27 while(j >= 0) {
28 chars[i] = chars[j];
29 if(chars[j] == '*') {
30 while(j >= 0 && chars[j] == '*'){
31 j--;
32 }
33 }
34 else {
35 j--;
36 }
37 i--;
38 }
39 return String.copyValueOf(chars, i + 1, chars.length - i - 1);
40 }
41 }
Solution 2. Dynamic Programming
1 public boolean isMatchDp(String str, String pattern) {
2 if(str == null || pattern == null) {
3 return false;
4 }
5 String newPattern = pattern.replaceAll("(\\*){2,}", "*");
6 boolean[][] T = new boolean[str.length() + 1][newPattern.length() + 1];
7 T[0][0] = true;
8 if(newPattern.length() > 0 && newPattern.charAt(0) == '*') {
9 T[0][1] = true;
10 }
11 for(int i = 1; i <= str.length(); i++) {
12 for(int j = 1; j <= newPattern.length(); j++) {
13 if(str.charAt(i - 1) == newPattern.charAt(j - 1) || newPattern.charAt(j - 1) == '?') {
14 T[i][j] = T[i - 1][j - 1];
15 }
16 else if(newPattern.charAt(j - 1) == '*') {
17 T[i][j] = T[i][j - 1] || T[i - 1][j];
18 }
19 else {
20 T[i][j] = false;
21 }
22 }
23 }
24 return T[str.length()][newPattern.length()];
25 }
Related Problems