https://leetcode.com/problems/implement-strstr/
还是有必要掌握的一个算法。
http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html
https://brickmaker.github.io/2018/08/19/kmp/
https://oi-wiki.org/string/kmp/#knuth-morris-pratt
个人解答
class Solution:def strStr(self, s: str, p: str) -> int:def genLPS(s):lps = [0] * len(s)i = 1l = 0while i < len(s):if s[i] == s[l]:l += 1lps[i] = li += 1elif l > 0:l = lps[l - 1]else:lps[i] = 0i += 1return lpslps = genLPS(p)# print(lps)if not p:return 0i, j = 0, 0while i < len(s):if s[i] == p[j]:i += 1j += 1if j == len(p):return i - jelif j > 0:j = lps[j - 1]else:i += 1return -1
题目分析
其实就是KMP算法的典型应用。
关于这个最长相同前缀后缀数组(LPS)的生成,可以考虑 lps[i] 表示 [0, i] 区间的,也可以表示 [0, i - 1] 区间的,就实现来说,前者更符合直觉,但是后者写起来可能更加简洁,更trick。
至于子字符串的问题,其实就是求s + ‘#’ + p这个字符串的LPS,因为求LPS的过程是个在线过程,所以,上述代码的 genLPS 函数和外部的代码高度相似(除了没有存lps数组)。
整个代码需要考虑好多关注点,尤其是,在之前判断or在之后判断?何时终止?都是需要想明白的。
