美文网首页
字符串匹配leetcode10

字符串匹配leetcode10

作者: CrazyTianC | 来源:发表于2019-01-29 11:28 被阅读2次

一般这种问题都往动态规划的方面去考虑。

所谓动态规划,最重要的就是得找到当前节点和前面之间的关系,写出来递推表达式,基本就求出来了。

这个题中,.代表任意一个字符,*匹配零个或多个前面的元素。

递归

情况一:下一个字符是* ,那就又分成两种情况,* 代表0个或者多个。代表0个的时候,说明* 没有用了,下一个pattern就需要跳过当前字符和下一个* ,所以是isMatch(text, pattern[2:])。匹配多个的话,那么需要检查当前text字符是否匹配first_match,以及text中的下一个字符是否符合当前pattern:isMatch(text[1:], pattern)

情况二:下一个字符不是* ,那么只要看text和pattern当前的字符是否匹配就行了。

class Solution(object):
    def isMatch(self, text, pattern):
        if not pattern:
            return not text

        first_match = bool(text) and pattern[0] in {text[0], '.'}

        if len(pattern) >= 2 and pattern[1] == '*':
            return (self.isMatch(text, pattern[2:]) or
                    first_match and self.isMatch(text[1:], pattern))
        else:
            return first_match and self.isMatch(text[1:], pattern[1:])

动态规划

我的理解是,动态规划和递归原理上是相同的,都是通过找到当前节点和下一个或者前一个节点之间的关系来实现,只是在递归的过程中,会发现有很多重复计算的过程,所以时间复杂度是指数级别的。因此对于那些重复算过的,其实我们可以不用在重复递归来算它的,可以把中间结果给保存起来,这种就是动态规划的思想。
要注意的就是边界条件。

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)

想要dp[j][i]为1,需要满足下面两个条件中的任意一个:
1、dp[j-2][i] = 1,此时* 代表空串
(注:text不变,如果当前是空串,那么说明pattern[j-2]和pattern[j]都能匹配这个text,所以有如上结论。)
2、dp[j][i-1] = 1 且 pattern字符串j-2位置的字符和目标字符串i-1位置的字符相同(因为0位置表示了空串,所以数组中i位置代表的是字符串中的i-1位置)或者说pattern字符串j-2位置的字符为'.',此时'*'表示对前一个字符的复制。

class Solution(object):
    def isMatch(self, text, pattern):
        dp = [[False] * (len(pattern) + 1) for _ in range(len(text) + 1)]

        dp[-1][-1] = True
        for i in range(len(text), -1, -1):
            for j in range(len(pattern) - 1, -1, -1):
                first_match = i < len(text) and pattern[j] in {text[i], '.'}
                if j+1 < len(pattern) and pattern[j+1] == '*':
                    dp[i][j] = dp[i][j+2] or first_match and dp[i+1][j]
                else:
                    dp[i][j] = first_match and dp[i+1][j+1]

        return dp[0][0]

参考:
leetcode10 solution
一招解决4道leetcode hard题

相关文章

  • 2017.5.15学习总结

    LeetCode10 这里s是要匹配的字符串,p是带有“ . ”和“ * ”的匹配串。这道题可以用递归和DP解决,...

  • 字符串匹配leetcode10

    一般这种问题都往动态规划的方面去考虑。 所谓动态规划,最重要的就是得找到当前节点和前面之间的关系,写出来递推表达式...

  • LeetCode热门100题算法和思路(day2)

    LeetCode10 正则表达式匹配 题目详情 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.'...

  • 大数据算法系列9:字符串匹配问题,海量字符串处理

    一. 字符串匹配 1.1 字符串匹配 字符串匹配:字符串匹配在实际工作中经常遇到,但是我们经常使用的是编程语言自带...

  • Python算法-字符串(String)

    字符串匹配问题字符串匹配(String Matching):又称为模式匹配(Pattern Matching)。可...

  • 正则表达式

    匹配位置: \b:单词的开头或者结束,单词的分界处^:匹配字符串的开始$:匹配字符串的结束 匹配字符 .:匹配除换...

  • iOS 字符串

    1、字符串的截取 2、匹配字符串 从字符串(sd是sfsfsAdfsdf)中查找(匹配)字符串(Ad) 3、字符串...

  • 字符串匹配

    indexOf 底层就是使用字符串匹配算法 字符串匹配算法很多 BF( Brute Force)算法 暴力匹配算...

  • 正则表达式

    基础语法 元字符^ 匹配行或者字符串的起始位置$ 匹配行或者字符串的结束位置\s 匹配空格\d 匹配数字\w 匹配...

  • iOS 字符串截取、iOS 字符串替换、iOS 字符串分隔、iO

    iOS之字符串截取、iOS 字符串替换、iOS字符串分隔、iOS之字符串匹配、截取字符串、匹配字符串、分隔字符串 ...

网友评论

      本文标题:字符串匹配leetcode10

      本文链接:https://www.haomeiwen.com/subject/csaajqtx.html