代码随想录训练营第九天 | 28. 实现 strStr() 459.重复的子字符串

KMP算法

解决字符串匹配问题:当出现字符串不匹配时,可以记录一部分之前已经匹配的文本内容,利用这些信息避免从头再去做匹配
暴力解决O(mn)
例:
文本串:aabaabaaf
模式串:aabaaf
从字符串index = 0开始匹配到index= 5时发现 不是f
下一步不是从index = 5开始冲头匹配aabaaf,二十congindex = 5开始匹配baaf

前缀表

用前缀表找到一个字符串的最长相等前后缀
aabaaf
前缀:a,aa,aab,aaba,aaba都是,aabaf不是前缀
后缀:f,af,aaf,baaf,abaaf都是
最长相等前后缀
a没有前缀和后缀,最长相等前后缀为0
aa 的最长相等为1
aab -> 0
aaba ->1
aabaa -> 2
aabaaf ->0
那么aabaaf的前缀表就是[0,1,0,1,2,0]

因此,从字符串index = 0开始匹配到index= 5时发现 不是f后,查看前缀表,f前面a对应的是2就继续对文本串后面尝试匹配模式串index = 2开始的内容

KMP求前缀表代码

a a b a a f
0 1 0 1 2 0
next数组

def getNext(next,s):
	# 1. 初始化
	j = 0 # 前缀末尾 = 
	next[0] = 0
	for i in range(1,len(s)):
		# 2. 前后缀不相同情况
		while j > 0 and s[i] != s[j]:
			j = next[i-1]
		# 3. 前后缀相同情况
		if s[i] == s[j]:
			j += 1
		# 4. 更新next
		next[i] = j
		

28. 实现 strStr()

初步想法

暴力

题解

https://programmercarl.com/0028.%E5%AE%9E%E7%8E%B0strStr.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE

class Solution:
    def getNext(self,next:List[int],s:str) -> None:
        # 1. 初始化
        j = 0 # 前缀末尾
        next[0] = 0
        for i in range(1,len(s)):
            # 2. 前后缀不相同情况
            while j > 0 and s[i] != s[j]:
                j = next[j-1]
            # 3. 前后缀相同情况
            if s[i] == s[j]:
                j += 1
            # 4. 更新next
            next[i] = j
  
    def strStr(self, haystack: str, needle: str) -> int:
        if len(needle) == 0:
            return 0
        next = [0]*len(needle)
        self.getNext(next,needle)
        j = 0
        for i in range(len(haystack)):
            while j > 0 and haystack[i] != needle[j]:
                j = next[j-1]
            if haystack[i] == needle[j]:
                j += 1
            if j == len(needle):
                return i - len(needle) + 1
        return -1

459.重复的子字符串

初步想法

放弃

题解

https://programmercarl.com/0459.%E9%87%8D%E5%A4%8D%E7%9A%84%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2.html
ss = s+s 去掉首位字母,然后 if s in ss: 说明可以
KMP:无法总结,看题解吧

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值