10.Regular Expression Matching (

2020-01-27  本文已影响0人  oneoverzero

题目描述:

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。

'.' 匹配任意单个字符
'*' 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个字符串 s 的,而不是部分字符串。

说明:

s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。

代码:

class Solution(object):
    def isMatch(self, text, pattern):
        if not pattern: return not text
        match_res = bool(text) and pattern[0] in {text[0], '.'} # 这里bool(text)的作用是为了保证后面的text[0]不会发生索引越界的情况(因为text有可能为空)
        
        if len(pattern) > 1 and pattern[1] == '*':
            return self.isMatch(text, pattern[2:]) or 
                   (match_res and self.isMatch(text[1:], pattern))
        else:
            return match_res and self.isMatch(text[1:], pattern[1:])

思路分析:

本题和《剑指offer》的第19题是一样的。如果 pattern 中没有 * ,则问题可以通过如下的递归来解决:

def match(text, pattern):
    if not pattern: return not text # 先写递归基
    match_res = bool(text) and pattern[0] in {text[0], '.'} # text只要不空,转化为bool均返回True
    return match_res and match(text[1:], pattern[1:])

* 出现时,前面一定会跟一个其他字符,所以每一次对 pattern 切片后,* 一定会出现在 pattern[1] 的位置。如何应对 * 出现时的情况呢?有如下两种解决方案:

可以看到,如果 pattern 中有 * ,则每一轮递归都有两条路可以选,而且在进入到下一轮递归后仍然有两条路可以选。

整个代码的思路是:

在代码中,or 之前的那个分支之所以没有加上对 match_res 的判断,是因为可能会出现下面这种情况:

输入:
s = "aab"
p = "c*a*b"
输出: true
解释: 因为 '*' 表示零个或多个,这里 'c' 为 0 个, 'a' 被重复一次。因此可以匹配字符串 "aab"。
上一篇 下一篇

猜你喜欢

热点阅读