-
Notifications
You must be signed in to change notification settings - Fork 0
/
211.py
67 lines (55 loc) · 1.55 KB
/
211.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
"""
Problem:
Given a string and a pattern, find the starting indices of all occurrences of the
pattern in the string. For example, given the string "abracadabra" and the pattern
"abr", you should return [0, 7].
"""
from typing import List
def kmp_search(string: str, pattern: str) -> List[int]:
pattern_length = len(pattern)
string_length = len(string)
lps = [0] * pattern_length
result = []
compute_lps(pattern, pattern_length, lps)
j = 0
i = 0
while i < string_length:
if pattern[j] == string[i]:
i += 1
j += 1
# entire pattern match
if j == pattern_length:
result.append(i - j)
j = lps[j - 1]
# mismatch after j positions
elif i < string_length and pattern[j] != string[i]:
if j != 0:
j = lps[j - 1]
else:
i += 1
return result
def compute_lps(pattern: str, pattern_length: int, lps: List[int]) -> None:
length = 0
lps[0]
i = 1
while i < pattern_length:
# match occours
if pattern[i] == pattern[length]:
length += 1
lps[i] = length
i += 1
continue
if length != 0:
length = lps[length - 1]
else:
lps[i] = 0
i += 1
if __name__ == "__main__":
print(kmp_search("abracadabra", "abr"))
print(kmp_search("abracadabra", "xyz"))
print(kmp_search("aaaa", "aa"))
"""
SPECS:
TIME COMPLEXITY: O(string_length + pattern_length)
SPACE COMPLEXITY: O(pattern_length)
"""