LeetCode 44. Wildcard Matching
September 02, 2020This problem can't be solved greedily due to examples like {s = 'ad', p = '*a*'}.
We can solve it with a dynamic programming solution.
import re
import unittest
class Test(unittest.TestCase):
def setUp(self):
self.s = Solution()
def test_examples(self):
self.assertFalse(self.s.isMatch("aa", "a"))
self.assertTrue(self.s.isMatch("aa", "*"))
self.assertFalse(self.s.isMatch("cb", "?a"))
self.assertTrue(self.s.isMatch("adceb", "*a*b"))
self.assertFalse(self.s.isMatch("acdcb", "a*c?b"))
self.assertFalse(self.s.isMatch("leetcode", "*e*t?d*"))
def test_asterisks(self):
self.assertTrue(self.s.isMatch("eraueheejdieae", "*e"))
class Solution:
def __init__(self):
# cache
self.c = {}
self.asteriskre = re.compile("^\**$")
def isMatch(self, s: str, p: str) -> bool:
if not s or not p:
# If we've exhausted either s or p,
# we have a match iff s is empty and p contains only *"s.
return not s and self.asteriskre.match(p)
if (s,p) in self.c:
return self.c[(s,p)]
if p[0] == "?" or p[0] == s[0]:
return self.isMatch(s[1:], p[1:])
if p[0] != "*":
return False
m = self.isMatch(s[1:], p)
if not m:
m = self.isMatch(s, p[1:])
self.c[(s,p)] = m
return m
if __name__ == "__main__":
unittest.main()