LeetCode-in-All

10. Regular Expression Matching

Hard

Given an input string s and a pattern p, implement regular expression matching with support for '.' and '*' where:

The matching should cover the entire input string (not partial).

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 preceding 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: false

Constraints:

Solution

class Solution {
    private $cache;

    /**
     * @param String $s
     * @param String $p
     * @return Boolean
     */
    public function isMatch($s, $p) {
        $this->cache = array_fill(0, strlen($s) + 1, array_fill(0, strlen($p) + 1, null));
        return $this->isMatchHelper($s, $p, 0, 0);
    }

    private function isMatchHelper($s, $p, $i, $j) {
        if ($j == strlen($p)) {
            return $i == strlen($s);
        }
        if ($this->cache[$i][$j] !== null) {
            return $this->cache[$i][$j];
        }
        $firstMatch = ($i < strlen($s)) && ($s[$i] == $p[$j] || $p[$j] == '.');
        if (($j + 1) < strlen($p) && $p[$j + 1] == '*') {
            $result = ($firstMatch && $this->isMatchHelper($s, $p, $i + 1, $j)) ||
                $this->isMatchHelper($s, $p, $i, $j + 2);
        } else {
            $result = $firstMatch && $this->isMatchHelper($s, $p, $i + 1, $j + 1);
        }
        $this->cache[$i][$j] = $result;
        return $result;
    }
}