KMP算法

KMP算法解决的问题:

 KMP算法解决字符串匹配问题,给两个字符串,查找其中一个字符串是否包含另一个字符串,如果包含,返回包含的起始位置
时间复杂度为 o(m+n)

KMP伪代码

  1. 在串S和串T中分别设比较的起始下标i和j
  2. 如果S和T的的所有字符未比较完,则循环
    2.1 如果S[i] == T[j],继续比较S和T的下一个字符
    2.2 否则将j滑向next[j]的位置,即 j = next[j]
    2.3 如果j == -1,则将i和j分别+1,准备下一趟比较
  3. 如果T中的字符串均比较完毕,则返回匹配的起始下标,否则返回-1

next数组求解

image.png

next数组的两种求解方式

直接插入-1法

懒猫老师-数据结构-(15)KMP算法2-next数组(模式匹配,字符串匹配)

n = len(needle)
prefixArr = [0] * n
j = -1
i = 0
prefixArr[0] = -1
while i < n - 1:
    if j == -1 or needle[j] == needle[i]:
        j += 1
        i += 1
        prefixArr[i] = j
    else:
        j = prefixArr[j]
直接插入-1法 感想
移位插入-1法

KMP字符串匹配算法
三哥讲解KMP算法part1
三哥讲解KMP算法part2之寻找前缀的方法

n = len(needle)
prefixArr = [0] * len(needle)
j = 0
i = 1
while i < n:
    if needle[j] == needle[i]:
        j += 1
        prefixArr[i] = j
        i += 1
    else:
        if j > 0:
            j = prefixArr[j - 1]
        else:
            prefixArr[i] = j
            i += 1
prefixArr.insert(0,-1)
prefixArr.pop()

28. 实现 strStr()


class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        m = len(haystack)
        n = len(needle)
        if m == 0 and n == 0 or n == 0:
            return 0
        i = 0
        j = 0
        nextArr = self.prefixArr(needle)
        while i < m and j < n:
            if j == n - 1 and haystack[i] == needle[j]:
                return i - j

            if j == -1 or haystack[i] == needle[j]:
                j += 1
                i += 1
            else:
                j = nextArr[j]
        return -1


    def prefixArr(self, s:str) -> list:
        j = -1
        i = 0
        n = len(s)
        nextArr = [0] * n
        nextArr[0] = j
        while i < n - 1:
            if j == -1 or s[i] == s[j]:
                j += 1
                i += 1
                nextArr[i] = j
            else:
                j = nextArr[j]
        return nextArr

你可能感兴趣的:(KMP算法)