leetcode - 回溯:10. Regular Expression Matching

topic:

Given an input string (s) and a pattern (p), 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).

Note:

  • s could be empty and contains only lowercase letters a-z.
  • p could be empty and contains only lowercase letters a-z, and characters like . or *.

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

 

Beginning the wrong question:

Mode that aa * bc * de * mean {[(aa) * n (bc)] * n (de)} * n [Note: * n represents a repeating n times]

Then with the following code:

class Solution:
    
    def isMatch_without(self,s,p):
        match = True
        for i in range(len(s)):
            if s[i] == p[i] or p[i]==".":
                pass
            else:
                match = False
                break
        return match
    
    def isMatch(self, s: str, p: str) -> bool:
        # 边缘情况
        if s == "":
            if p == "":
                return True
            elif p[-1] == "*":
                return True
            else:
                return False
        
        match = True
        ps = str.split(p, "*")
        
        #如果不是以 * 结尾
        if ps[-1] !="":
            match = self.isMatch_without(s[-len(ps[-1]):],ps[-1])
            if match:
                s = s[:-len(ps[-1])]
            else:
                return False
                        
        ps.pop()
        index_p = len(ps)
        if index_p ==0 and s!="":
            return False
        while s!="":
            if index_p>0:
                index_p -=1
            else:
                index_p = len(ps)-1
            if len(s) >= len(ps[index_p]):
                match = self.isMatch_without(s[-len(ps[index_p]):],ps[index_p])
            else:
                match = False
            if match:
                while match & (s!=""):
                    s = s[:-len(ps[index_p])]
                    if len(s) >= len(ps[index_p]):
                        match = self.isMatch_without(s[-len(ps[index_p]):],ps[index_p])
                    else:
                        match = False
            else:
                index_p = len(ps) - 1
                if len(s) >= len(ps[index_p]):
                    match = self.isMatch_without(s[-len(ps[index_p]):],ps[index_p])
                else:
                    match = False
                if not match:
                    return False
                else:
                    while match & (s!=""):
                        s = s[:-len(ps[index_p])]
                        if len(s) >= len(ps[index_p]):
                            match = self.isMatch_without(s[-len(ps[index_p]):],ps[index_p])
                        else:
                            match = False
        return True
                
        

 

It was found that the subject is not so complicated,

Mode is aa * bc * de * means: 

a (a) * nb (c) * nd (e) * n, a result, this becomes a problem backtracking. For x * mode requires two steps:

1, s does not delete x (x times repeated in s 0), x * delete pattern p determines whether to go through;

2, when a dead end is deleted s x, x * p Retains mode determines whether to go through (backtracking through continuous, may be implemented to remove n times s x, x * p deleted)

class Solution:
    
    def isMatch(self, s: str, p: str) -> bool:
        i = len(p)-1
        while i >=0:
            if p[i] == "*":
                i -= 1

                # 假设s中不包含 * 前面的字符,尝试看是否走得通
                if self.isMatch(s,p[:i]):
                    return True

                # 走不通,回溯,看能否删一个字符
                else:
                    while len(s)>0:
                        if p[i]=="." or s[-1]==p[i]:
                            s = s[:-1]
                            if self.isMatch(s,p[:i]):
                                return True
                        else:
                            i -= 1
                            break

            # 不含*的普通模式,没有分枝
            else:
                if len(s)>0:
                    if p[i]=="." or s[-1]==p[i]:
                        i -= 1
                        s = s[:-1]
                    else:
                        return False
                else:
                    return False
                
        if len(s) ==0:
            return True
        else:
            return False
                
                       

 

This problem must be back, do not go back, there will be special consideration multilateral corners less.

 

发布了45 篇原创文章 · 获赞 1 · 访问量 3383

Guess you like

Origin blog.csdn.net/qq_22498427/article/details/104437940