Implement regular expression matching with support for ‘.’ and ‘*’.
‘.’ Matches any single character.
‘*’ Matches zero or more of the preceding element.
The matching should cover the entire input string (not partial).
The function prototype should be:
bool isMatch(const char s, const char p)
Some examples:
1 2 3 4 5 6 7
| isMatch("aa","a") → false isMatch("aa","aa") → true isMatch("aaa","aa") → false isMatch("aa", "a*") → true isMatch("aa", ".*") → true isMatch("ab", ".*") → true isMatch("aab", "c*a*b") → true
|
DP solution
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| public class Solution { * match[i][j]: if s[0...i-1] matches p[0...j-1] * if p[j-1] != '*': * match[i][j] = match[i-1][j-1] && s[i-1] = p[j-1] * if p[j-1] == '*', denote x = p[j-2]: * match[i][j] is true iff meets one of the following: * "x*" repeats 0 time and matches empty: match[i][j-2] * "x*" repeats >= 1 time and matches "x*x": s[i-1] == x && match[i-1][j] **/ public boolean isMatch(String s, String p) { if (p == null){return s == null;} int pLength = p.length(), sLength = s.length(); boolean[][] match = new boolean[sLength + 1][pLength + 1]; match[0][0] = true; for (int i = 1; i <= sLength; i++){ match[i][0] = false; } for (int j = 1; j <= pLength; j++){ match[0][j] = (j > 1 && p.charAt(j - 1) == '*' && match[0][j - 2]); } for (int i = 1; i <= sLength; i++){ for (int j = 1; j <= pLength; j++){ if (p.charAt(j - 1) != '*'){ match[i][j] = match[i - 1][j - 1] && charMatch(s.charAt(i - 1), p.charAt(j - 1)); }else{ match[i][j] = match[i][j - 2] || (charMatch(s.charAt(i - 1), p.charAt(j - 2)) && match[i - 1][j]); } } } return match[sLength][pLength]; } public boolean charMatch(char s, char p){ return p == '.' || s == p; } }
|
Recursive solution
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class Solution { public boolean isMatch(String s, String p) { if (p.isEmpty()){return s.isEmpty();} if (p.length() == 1 || p.charAt(1) != '*'){ if (s.isEmpty() || !charMatch(s.charAt(0), p.charAt(0))){ return false; }else{ return isMatch(s.substring(1),p.substring(1)); } } while(!s.isEmpty() && charMatch(s.charAt(0), p.charAt(0))){ if (isMatch(s, p.substring(2))){return true;} s = s.substring(1); } return isMatch(s, p.substring(2)); } public boolean charMatch(char s, char p){ return p == '.' || p == s; } }
|