Regular Expression Matching

Given string s and pattern p with . and * support, implement regular expression matching. . matches any single character, * matches zero or more of the preceding element.

Example 1
Input: s="aa", p="a*" → Output: true
Example 2
Input: s="ab", p=".*" → Output: true

Solution Approach

dp[i][j] = whether s[0..i-1] matches p[0..j-1]. Handle * by either skipping the preceding pattern element or consuming one character from s.

  • dp[0][0] = true; dp[0][j] = true if pattern[j-1]=="*" and dp[0][j-2].
  • If p[j-1]==s[i-1] or p[j-1]==".": dp[i][j] = dp[i-1][j-1].
  • If p[j-1]=="*": zero occurrences dp[i][j-2], or one+ occurrences dp[i-1][j] if p[j-2] matches s[i-1].
Java
class Solution {
    public boolean isMatch(String s, String p) {
        int m = s.length(), n = p.length();
        boolean[][] dp = new boolean[m + 1][n + 1];
        dp[0][0] = true;
        for (int j = 2; j <= n; j += 2)
            if (p.charAt(j-1) == '*') dp[0][j] = dp[0][j-2];
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (p.charAt(j-1) == '*') {
                    dp[i][j] = dp[i][j-2]; // zero
                    if (p.charAt(j-2) == '.' || p.charAt(j-2) == s.charAt(i-1))
                        dp[i][j] = dp[i][j] || dp[i-1][j]; // one+
                } else if (p.charAt(j-1) == '.' || p.charAt(j-1) == s.charAt(i-1)) {
                    dp[i][j] = dp[i-1][j-1];
                }
            }
        }
        return dp[m][n];
    }
}
  • Time Complexity: O(M*N)
  • Space Complexity: O(M*N)