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

代码随想录刷题第九天

实现 strStr() (LC 28) (很难,一刷不一定掌握)

实现 strStr() 函数。

给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1

示例 1: 输入: haystack = “hello”, needle = “ll” 输出: 2

示例 2: 输入: haystack = “aaaaa”, needle = “bba” 输出: -1

说明: 当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。 对于本题而言,当 needle 是空字符串时我们应当返回 0。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。

本题是KMP 经典题目。KMP的经典思想就是:当出现字符串不匹配时,可以记录一部分之前已经匹配的文本内容,利用这些信息避免从头再去做匹配。

在这里插入图片描述
在这里插入图片描述

代码实现:

class Solution(object):
    def strStr(self, haystack, needle):
        if len(needle) == 0:
            return 0
        next1 = self.getNext(needle)
        print(next1)
        j = 0
        for i in range(len(haystack)):
            while j>0 and haystack[i] != needle[j]:
                j = next1[j-1]
            if haystack[i] == needle[j]:
                j+=1
            if j == len(needle):
                return i-len(needle)+1
        return -1
        

    def getNext(self, needle):
        next1 = [0 for _ in range(len(needle))]
        j = 0
        next1[0] = 0
        for i in range(1, len(needle)):
            while j>0 and needle[i]!=needle[j]:
                j = next1[j-1]
            if needle[i] == needle[j]:
                j+=1
            next1[i] = j
        return next1

重复的子字符串 (LC 459)

给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。

示例:

输入: “abab”
输出: True
解释: 可由子字符串 “ab” 重复两次构成。

输入: “aba”
输出: False

输入: “abcabcabcabc”
输出: True
解释: 可由子字符串 “abc” 重复四次构成。 (或者子字符串 “abcabc” 重复两次构成。)

移动匹配:
如果一个字符串S是由一个子字符串组成的,则该两倍的该字符串S+S前后相连,中间还能组成一个字符串S.

在这里插入图片描述

代码实现:

class Solution:
    def repeatedSubstringPattern(self, s: str) -> bool:
        n = len(s)
        if n <= 1:
            return False
        ss = s[1:] + s[:-1] 
        print(ss.find(s))              
        return ss.find(s) != -1

KMP
一个字符串的最大公共前后缀, 如果前缀是从字符串第一个元素开始的,后缀是从字符串最后一个元素开始的,则前后缀没包含的元素则为重复子串,具体思路如下:

在这里插入图片描述
代码实现:

class Solution(object):
    def repeatedSubstringPattern(self, s):
        if len(s) == 0:
            return False
        nxt = self.getNext(s)
        if nxt[-1]!=0 and len(s) % (len(s) - nxt[-1])==0:
            return True
        return False
        

    def getNext(self, s):
        nxt = [0]*len(s)
        j = 0
        nxt[0] = 0
        for i in range(1, len(s)):
            while (j>0 and s[i]!=s[j]):
                j = nxt[j-1]
            if s[i]==s[j]:
                j+=1
            nxt[i] = j
        return nxt

总结:

今天主要学习了KMP算法,前缀表怎么构造。如果当前i=j,j+1; 如果i!=j, j=next[j-1]; next[i]=j

KMP很难,二刷还要持续复习!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值