【LeetCode 刷题】字符串-字符串匹配(KMP)

此博客为《代码随想录》字符串章节的学习笔记,主要内容为字符串匹配 KMP 算法相关的题目解析。

文章目录

  • [28. 找出字符串中第一个匹配项的下标](#28. 找出字符串中第一个匹配项的下标)
  • [459. 重复的子字符串](#459. 重复的子字符串)

28. 找出字符串中第一个匹配项的下标

题目链接

python 复制代码
class Solution:
    def getNext(self, s: str) -> List[int]:
        j, nxt = 0, [0] * len(s)
        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
        
    def strStr(self, haystack: str, needle: str) -> int:
        j, nxt = 0, self.getNext(needle)
        for i in range(len(haystack)):
            while j > 0 and haystack[i] != needle[j]:
                j = nxt[j - 1]
            if haystack[i] == needle[j]:
                j += 1
            if j == len(needle):
                return i - j + 1
        return -1
  • getNext 用于计算 next 数组,next 数组是模式串的特征规律,与文本串无关
  • 在此代码中的 next 数组的定义下,每次遇到矛盾,都需要查找上一个元素next 数组中的值,以确定回溯位置
  • getNext 函数中 j 表示的是目前最长公共前后缀的长度(也指向着公共前缀的末尾);i 指向着公共后缀的末尾
  • getNext 的 for 循环:i 从 1 开始 ,因为 i 为 0 时表示着长度为 1 的串,最长公共前后缀长度为 0,即 next[0] = 0(在数组初始化时已经完成)
  • strStr 的 for 循环:i 从 0 开始 ,完整遍历文本串 haystack

459. 重复的子字符串

题目链接

python 复制代码
class Solution:
    def getNext(self, s: str) -> List[int]:
        j, nxt = 0, [0] * len(s)
        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

    def repeatedSubstringPattern(self, s: str) -> bool:
        nxt = self.getNext(s)
        if nxt[-1] != 0 and len(s) % (len(s) - nxt[-1]) == 0:
            return True
        return False
  • 如果字符串 s 是由重复子串组成,那么最长相等前后缀不包含的子串 一定是 s 的最小重复子串,证明过程
  • 因此仿照 KMP 算法计算 next 数组,判断是否存在最长相等前后缀,以及最长相等前后缀不包含的子串的长度 len(s) - nxt[-1] ,是否能够被原字符串长度整除

移动匹配法(通用做法)

python 复制代码
class Solution:
    def repeatedSubstringPattern(self, s: str) -> bool:
        s_ = (s + s)[1:-1]
        return s in s_
  • 自身加自身得到 s_,之后移除第一和最后一个元素(破坏原始串),判断 s_ 中是否包含自身 s
相关推荐
️是78几秒前
信息奥赛一本通—编程启蒙(3346:【例60.3】 找素数)
数据结构·c++·算法
captain3762 分钟前
map和set
数据结构·算法
qq_416018725 分钟前
实时数据可视化库
开发语言·c++·算法
阿钱真强道5 分钟前
27 Python 分类-从概率角度做分类,一文认识朴素贝叶斯
python·分类·朴素贝叶斯·分类算法·贝叶斯分类·gaussiannb
格林威5 分钟前
工业相机参数解析:曝光时间与运动模糊的“生死博弈”
c++·人工智能·数码相机·opencv·算法·计算机视觉·工业相机
2401_8732046518 分钟前
C++中的策略模式进阶
开发语言·c++·算法
xushichao198923 分钟前
C++中的职责链模式实战
开发语言·c++·算法
2301_7765087223 分钟前
Python日志记录(Logging)最佳实践
jvm·数据库·python
大鹏说大话30 分钟前
数据库查询优化全攻略:从索引设计到架构演进
算法
小O的算法实验室30 分钟前
2025年IEEE TETCI SCI2区,一种用于二次无约束二进制优化的协同神经动力学算法,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进