-
Notifications
You must be signed in to change notification settings - Fork 17
/
longest-happy-prefix.py
73 lines (51 loc) · 2.03 KB
/
longest-happy-prefix.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
68
69
70
71
72
73
from typing import List
class RollingHash:
def __init__(self, string: str) -> None:
self._hash = 0
self._pow = 1
self._alphabet_size = 26
self._mod = 2 ** 63
for char in string:
self.append(char)
@staticmethod
def _char_to_int(char: str) -> int:
return ord(char) - ord("a") + 1
def append(self, char: str) -> None:
self._pow *= self._alphabet_size
self._hash = (
int(self._hash * self._alphabet_size + self._char_to_int(char)) % self._mod
)
def appendleft(self, char: str) -> None:
self._hash = int(self._hash + self._char_to_int(char) * self._pow) % self._mod
self._pow *= self._alphabet_size
def popleft(self, char: str) -> None:
self._pow //= self._alphabet_size
self._hash -= int(self._pow * self._char_to_int(char)) % self._mod
def __hash__(self) -> int:
return self._hash
def __repr__(self) -> str:
return str(self._hash)
def compute_prefix_function(pattern: str) -> List[int]:
prefix_function = [0] * len(pattern)
matched = 0
for pos in range(1, len(pattern)):
while matched != 0 and pattern[matched] != pattern[pos]:
matched = prefix_function[matched - 1]
if pattern[matched] == pattern[pos]:
matched += 1
prefix_function[pos] = matched
return prefix_function
class Solution:
def longestPrefix(self, string: str) -> str:
return string[: compute_prefix_function(string)[-1]]
def longestPrefixRabinKarp(self, string: str) -> str:
hash_left_right = RollingHash("")
hash_right_left = RollingHash("")
longest_prefix = ""
for pos in range(len(string) - 1):
hash_left_right.append(string[pos])
hash_right_left.appendleft(string[-pos - 1])
if hash(hash_left_right) == hash(hash_right_left):
if string[: pos + 1] == string[-pos - 1 :]:
longest_prefix = string[: pos + 1]
return longest_prefix