Skip to content

New Match

def isMatch(s, p):
    dp = {}

    def dfs(i, j):  # current posn of s and p
        # match : no problems till now : base case
        if i == len(s) and j == len(p):
            return True  # reached full pattern
        # ran out of patterns
        if j == len(p):  # run out of pattern characters
            return False  # not match

        if (i, j) in dp:
            return dp[(i, j)]  # memoized..

        # if curr char posn at i and j match.
        match = i < len(s) and (s[i] == p[j] or p[j] == "?")

        # mutli character
        if p[j] == "*":
            # match empty character or match one/more character from s
            dp[(i, j)] = dfs(i, j + 1) or (i < len(s) and dfs(i + 1, j))
            return dp[(i, j)]

        if match:  # do for next character also
            dp[(i, j)] = dfs(i + 1, j + 1)
            return dp[(i, j)]

        dp[(i, j)] = False  # if no above conditions met : not match
        return False

    return dfs(0, 0)


# worst case : exponential time complexity
# O(len(s) * len(p)) : space complexity

"""
Rules to write Recurrence.
1) Express (i,j)
2) Explore comparisions
3) Out of all comparisions if any way can : true

Matching conditions
if (s[i] = p[j]) || s[i] == '?': return f(i+1, j+1)
if (s[i] == '*') f(i-1, j) : length 0 OR f(i, j - single char matching condition1) : next character
"""