KMP¶
Table of Contents¶
- 28. Find the Index of the First Occurrence in a String (Easy)
- 459. Repeated Substring Pattern (Easy)
- 686. Repeated String Match (Medium)
- 1392. Longest Happy Prefix (Hard)
- 214. Shortest Palindrome (Hard)
28. Find the Index of the First Occurrence in a String¶
from leetpattern.utils import LPS
# Brute Force
def strStrBF(haystack: str, needle: str) -> int:
m, n = len(haystack), len(needle)
for i in range(m - n + 1):
if haystack[i : i + n] == needle:
return i
return -1
# KMP
def strStrKMP(haystack: str, needle: str) -> int:
lps = LPS(needle)
m, n = len(haystack), len(needle)
j = 0
for i in range(m):
while j > 0 and haystack[i] != needle[j]:
j = lps[j - 1]
if haystack[i] == needle[j]:
j += 1
if j == n:
return i - n + 1
return -1
# |------------|------------------|---------|
# | Approach | Time | Space |
# |------------|------------------|---------|
# | Brute Force| O((m - n) * n) | O(1) |
# | KMP | O(m + n) | O(n) |
# |------------|------------------|---------|
haystack = "hello"
needle = "ll"
print(strStrBF(haystack, needle)) # 2
print(strStrKMP(haystack, needle)) # 2
459. Repeated Substring Pattern¶
686. Repeated String Match¶
import math
from leetpattern.utils import LPS
# KMP
def repeatedStringMatch(a: str, b: str) -> int:
min_repeat = math.ceil(len(b) / len(a))
def kmp(text, pattern):
n, m = len(text), len(pattern)
lps = LPS(pattern)
j = 0
for i in range(n):
while j > 0 and text[i] != pattern[j]:
j = lps[j - 1]
if text[i] == pattern[j]:
j += 1
if j == m:
return i - j + 1
return -1
for i in range(min_repeat, min_repeat + 2):
if kmp(a * i, b) != -1:
return i
return -1
print(repeatedStringMatch("abcd", "cdabcdab")) # 3