Given an input string (s) and a pattern (p), 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).
Note:
s could be empty and contains only lowercase letters a-z.p could be empty and contains only lowercase letters a-z, and characters like . or *.Example 1:
Input:
s = "aa"
p = "a"
Output: false
Explanation: "a" does not match the entire string "aa".Example 2:
Input:
s = "aa"
p = "a*"
Output: true
Explanation: '*' means zero or more of the precedeng element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".Example 3:
Input:
s = "ab"
p = ".*"
Output: true
Explanation: ".*" means "zero or more (*) of any character (.)".Example 4:
Input:
s = "aab"
p = "c*a*b"
Output: true
Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore it matches "aab".Example 5:
Input:
s = "mississippi"
p = "mis*is*p*."
Output: falseProblem link
You can find the detailed video tutorial here
The thought process is very similar to Leetcode Solution 44: Wildcard Matching, you can find the blog here and the video tutorial here. Step 0 really is to understand what the "*" really means.
'*' Matches zero or more of the preceding element.A few examples,
The first attempt (if you haven't seen this question before) is trying to solve it using recursion. The idea is simple. While comparing the s and p char by char, as soon as you see a "*", you will start recurse
The time complexity in a ballpark looks like exponential to the P length, but a more detailed analysis from leetcode's original solution can be found here. If you recall what problems can be solved using DP, DP (Dynamic Programming) is normally a great way when trying to answer below two types of questions, and string related questions are a majority use case of DP
I have posted several videos on how to solve DP problems using a template, essentially
This problem can be solved using DP by having formulas like below when a "*" is see



Once you have the formula, coding up DP problem should be a piece of cake. You can find the video tutorial on this problem here
public boolean isMatch(String s, String p) { | |
|---|---|
if (s == null || p == null) { | |
return false; | |
} | |
int row = s.length(); | |
int col = p.length(); | |
boolean[][] lookup = new boolean[row + 1][col + 1]; | |
lookup[0][0] = true; | |
// init the init values | |
for (int j = 1; j <= col; j++) { | |
if (p.charAt(j - 1) == '*') { | |
if (lookup[0][j - 1]) { | |
lookup[0][j] = true; | |
} else if (j >= 2 && lookup[0][j - 2]) { | |
lookup[0][j] = true; | |
} | |
} | |
} | |
for (int i = 1; i <= row; i++) { | |
for (int j = 1; j <= col; j++) { | |
if (p.charAt(j - 1) == '*') { | |
// in the graph above referred as first if | |
if (lookup[i][j - 1]) { | |
lookup[i][j] = true; | |
} | |
// in the graph above referred as second if | |
if (!lookup[i][j] && lookup[i - 1][j]) { | |
lookup[i][j] = (s.charAt(i - 1) == p.charAt(j - 2) || p.charAt(j - 2) == '.'); | |
} | |
// in the graph above referred as third if | |
if (!lookup[i][j] && j >= 2 && lookup[i][j - 2]) { | |
lookup[i][j] = true; | |
} | |
} else { | |
if (lookup[i - 1][j - 1] && ((p.charAt(j - 1) == s.charAt(i - 1)) || p.charAt(j - 1) == '.')) { | |
lookup[i][j] = true; | |
} | |
} | |
} | |
} | |
// Utilities.printBooleanMatrix(lookup); | |
return lookup[row][col]; | |
} |
view rawRegularExpresionMatching.java hosted with ❤ by GitHub
Time Complexity: assuming S length is M, P length is N, this is O(M*N) because all we need to do is build up that lookup matrix Space Complexity: assuming S length is M, P length is N, this is O(M*N), again, that lookup matrix