Leetcode28. 实现strStr()

94 篇文章 0 订阅
94 篇文章 6 订阅

题目大意:实现字符串匹配函数,即在文本串S中查找一个模式串P的出现位置,若不出现返回-1

题目分析:暴力解法,将模式串P与文本串S一位一位的比较,若相同,则继续比较下一位;若不同,则将模式串P向后移动一位,继续往后比较。时间复杂度为O(m*n),假设文本串S的长度为m,模式串P的长度为n。

代码展示:

class Solution(object):
    def strStr(self, haystack, needle):
        sLen = len(haystack)
        pLen = len(needle)
        i = 0
        j = 0
        while i<sLen and j<pLen:
            if haystack[i]==needle[j]:
                i += 1
                j += 1
            else:
                i = i-j+1
                j = 0
        if j==pLen:
            return i-j
        else:
            return -1


方法二:使用KMP算法,将时间复杂度降到O(m+n),KMP算法的主要思想是当出现字符串不匹配时,将模式串移动几位,而不是每次都向后移动一位。移动的位数 = 不匹配字符所在位置 - 不匹配字符对应的next值。

next数组的含义是:若next[j]=k,则表示j之前字符串中有最大长度为k的相同前缀、后缀。

举个例子,假设模式串为ABCDABD,则next数组表是这样的:

模式串ABCDABD
next数组-1000012

解释:令第一个字符A的next值为-1,第二个字符B前面的字符串为A,它的相同的前缀后缀为0。什么是相同的前缀后缀呢?比如说,ABCAB,这里AB就是相同的前缀后缀,长度为2。因为AB在字符串的前面后面都出现了。同理,再来观察模式串,最后一个字符D的next值为2,表示它前面的字符串ABCDAB有长度为2的相同的前缀后缀。

代码展示:

class Solution(object):
    def strStr(self, haystack, needle):
        sLen = len(haystack)
        pLen = len(needle)
        nextNum = self.getNext(needle)
        i = 0
        j = 0
        while i<sLen and j<pLen:
            if j==-1 or haystack[i]==needle[j]:
                i += 1
                j += 1
            else:
                j = nextNum[j]
        if j==pLen:
            return i-j
        else:
            return -1
    
    def getNext(self,needle):
        nextNum = []
        pLen = len(needle)
        nextNum.append(-1)
        k = -1
        j = 0
        while j<pLen-1:
            if k==-1 or needle[k]==needle[j]:
                k += 1
                j += 1
                nextNum.append(k)
            else:
                k = nextNum[k]
        return nextNum
关于KMP算法的主要思想, 点这里
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值