LeetCode 10 Regular Expression Matching (C++, Python)

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

Solution C++


 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
class Solution {
public:
    bool isMatch(string s, string p) {
        if (s == p) return true;
        if (p.empty()) return false;
        const int M = s.length();
        const int N = p.length();
        vector<vector<char>> dp(M + 1, vector<char>(N + 1, false));
        dp[M][N] = true;
        for (int j = N - 1; j >= 0; j -= 2) {
            if (dp[M][j + 1] == false) break;
            if (j == 0) {
                dp[M][j] = false;
                continue;
            }
            if (p[j] == '*') {
                dp[M][j] = false;
                dp[M][j - 1] = true;
            }
        }
        for (int i = M - 1; i >= 0; -- i) {
            if (s[i] == p[N - 1] || p[N - 1] == '.') dp[i][N - 1] = dp[i + 1][N];
        }
        for (int i = M - 1; i >= 0; -- i) {
            for (int j = N - 2; j >= 0; -- j) {
                if (p[j] == '.' && p[j + 1] == '*') {
                    dp[i][j] = dp[i][j + 2] || dp[i + 1][j];
                } else if (p[j + 1] == '*') {
                    dp[i][j] = dp[i][j + 2] || ((s[i] == p[j]) && dp[i + 1][j]); 
                } else if (s[i] == p[j] || p[j] == '.') {
                    dp[i][j] = dp[i + 1][j + 1];
                }
            }
        }
        return dp[0][0];
    }
};

Solution Python


 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
class Solution:
    def isIntMatch(self, s, p, cache):
        if (s, p) in cache:
            return cache[(s, p)]
        if s == p:
            cache[(s, p)] = True
            return True
        if not p:
            cache[(s, p)] = False
            return False
        if not s:
            for i in range(0, len(p), 2):
                if (i + 1) == len(p):
                    cache[(s, p)] = False
                    return False
                if p[i + 1] != '*':
                    cache[(s, p)] = False
                    return False
            cache[(s, p)] = True
            return True
        if len(p) > 1:
            if p[:2] == '.*':
                ret = self.isIntMatch(s, p[2:], cache) or self.isIntMatch(s[1:], p, cache)
                cache[(s, p)] = ret
                return ret
            if p[1] == '*':
                ret = self.isIntMatch(s, p[2:], cache) or (s[0] == p[0] and self.isIntMatch(s[1:], p, cache))
                cache[(s, p)] = ret
                return ret
        if p[0] == s[0] or p[0] == '.':
            ret = self.isIntMatch(s[1:], p[1:], cache)
            cache[(s, p)] = ret
            return ret
        cache[(s, p)] = False
        return False
            
    # @param {string} s
    # @param {string} p
    # @return {boolean}
    def isMatch(self, s, p):
        cache = {}
        return self.isIntMatch(s, p, cache)

Popular posts from this blog

How Django Works (4) URL Resolution

Python Class Method and Class Only Method

How Django works (3): Testing Server and Static Files Serving