[Leetcode Series] [algorithm] [difficult] regular expression match

topic:

Topic links:  https://leetcode-cn.com/problems/regular-expression-matching/

 

Problem-solving ideas:

Method One: backtracking

Because it is required to match the entire string, not commonly appreciated that an arbitrary position matching, so from the beginning of the match, s, p

The leading character p there are so few cases:

  1. '.', It represents any single character
  2. Az any lowercase letter, a character according to the following case, it is necessary to distinguish two cases treated
    1. '*', Which matches any character
    2. Any lowercase letters az, representing the current character must match

According to the above, when the matching process substantially as follows:

  1. Check the first character of p, is '.' S first character or
  2. If the second p characters is '*', then the next record twice recursive calls
    1. If the first character of p, s match with the first character, the recursive call, the value of p continue unchanged, the value of s starting from the second character, the purpose is to match a plurality of first character appears , i.e. when the calling parameters (s [1:], p)
    2. If the first character is not a match, then the recursive call, the value of s constant, P starts from the third character, the purpose of eliminating matching '*', and the latter continues to match, i.e., parameter (s call when , p [2:])
  3. Other cases, if the first character does not match, then the direct return False, if the first character to match, skip the first character of s and p, calls itself recursively, ie parameters for the call (s [1:], p [1:] )

Matching process shown as follows:

Assuming matching, s = 'aab', p = 'c * a * b *', the matching process is as follows:

a a b    
c * a * b

Does not match the first character, the second character is of p *, s constant, update p = p [2:] = 'a * b', again recursively:

a a b
a * b

Matches the first character, the second character is of p *, p unchanged, update s = s [1:] = 'ab', again recursively:

a b  
a * b

Matches the first character, the second character is of p *, p unchanged, update s = s [1:] = 'b', again recursively:

b    
a * b

Does not match the first character, the second character is of p *, s constant, update p = p [2:] = 'b':

b
b

The first character to match, and no follow-up s and p character, and returns True

 

Method two: backtracking + DP

The basic method matches with the same method, different places to add a variable to save the results traversed reduce recursive calls, improve efficiency

 

Code:

method one:

class Solution:
    def isMatch(self, s: str, p: str) -> bool:
        if not p:
            return not s
        
        first_match = bool(s and p[0] in ['.', s[0]])
        if len(p) >= 2 and p[1] == '*':
            return self.isMatch(s, p[2:]) or (first_match and self.isMatch(s[1:], p))
        else:
            return first_match and self.isMatch(s[1:], p[1:])

 

Method Two:

class Solution(object):
    def isMatch(self, text, pattern):
        memo = {}
        def dp(i, j):
            if (i, j) not in memo:
                if j == len(pattern):
                    ans = i == len(text)
                else:
                    first_match = i < len(text) and pattern[j] in {text[i], '.'}
                    if j+1 < len(pattern) and pattern[j+1] == '*':
                        ans = dp(i, j+2) or first_match and dp(i+1, j)
                    else:
                        ans = first_match and dp(i+1, j+1)

                memo[i, j] = ans
            return memo[i, j]

        return dp(0, 0)

作者:LeetCode
链接:https://leetcode-cn.com/problems/regular-expression-matching/solution/zheng-ze-biao-da-shi-pi-pei-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

Published 100 original articles · won praise 4 · Views 1475

Guess you like

Origin blog.csdn.net/songyuwen0808/article/details/105303262