代码随想训练营第九天(Python)| 实现 strStr()、459.重复的子字符串
实现 strStr()
kmp 算法
一、暴力解法
class Solution:
def strStr(self, haystack: str, needle: str) -> int:
m, n = len(haystack), len(needle)
for i in range(m):
if haystack[i:i+n] == needle:
return i
return -1
二、kmp
思考点
1、在遇到 needle 字符与 haystack 字符不相等时,指向 needle 位置的指针不需要每次都指向开始位置 0。可以根据 next 数组后退到相对应地位置,因为指向过 haystack 的后面字符可能与 needle 前面的字符相等。
2、next 数组用于存储 needle 每个字符位置不与 haystack 字符不相等时应该回归到这个字符的哪一个位置。前后缀相等的最长距离。
3、next 数组的实现。i 指向前缀的末尾位置,j 指向后缀的末尾位置。
class Solution:
def strStr(self, haystack: str, needle: str) -> int:
n, m = len(haystack), len(needle)
next = m*[0]
self.get_next(next, needle)
j = 0
for i in range(n):
while j > 0 and haystack[i] != needle[j]:
j = next[j-1]
if haystack[i] == needle[j]:
j += 1
if j == m:
return i-m+1
return -1
def get_next(self, next: list, s: str):
# j 指向前缀末尾位置,i 指向后缀末尾位置
# 初始化
j = 0
next[0] = j
for i in range(1, len(s)):
while j > 0 and s[i] != s[j]: # 不相等,后退
j = next[j-1]
if s[i] == s[j]:
j += 1
next[i] = j
return next
class Solution:
def repeatedSubstringPattern(self, s: str) -> bool:
return True if s in (s+s)[1:-1] else False