-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfind_all_anagrams_in_a_string.py
75 lines (59 loc) · 2.66 KB
/
find_all_anagrams_in_a_string.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
74
75
import collections
from typing import List
def test_1():
s = "cbaebabacd"
p = "abc"
assert Solution().findAnagrams(s, p) == [0, 6]
def test_2():
s = "baa"
p = "aa"
assert Solution().findAnagrams(s, p) == [1]
def encode_string(s: str) -> collections.defaultdict:
"""
Преобразуем строку в хеш-таблицу с количеством повторений символов char->count
"""
res = collections.defaultdict(int)
for c in s:
res[c] += 1
return res
def is_anagram(window_code: dict, p_code: dict) -> bool:
"""
Проверка, что закодированные строки являются анаграммами.
Т.е количество повторений для каждого символа в таблицах равны.
"""
for char, count in window_code.items():
if count > 0 and (char not in p_code or p_code[char] != count):
return False
return True
class Solution:
def findAnagrams(self, s: str, p: str) -> List[int]:
"""
Time Complexity: O(N), where N is the length of S.
Space Complexity: O(1) to keep data structure last of not more than 26 characters.
"""
if len(s) < len(p):
return []
l, r = 0, len(p)
# Кодируем входящую строку р
p_code = encode_string(p)
# Кодируем окно, равное длине входящей строки р
window_code = encode_string(s[l:r])
res = []
# Пока правый край окна не достигнет конца строки S
while r < len(s):
# Проверяем на анаграмму
if is_anagram(window_code, p_code):
res.append(l)
# Удаляем левый символ из кодированного представления окна
left_char = s[l]
window_code[left_char] -= 1
# Добавляем правый символ к кодированному представления окна(изначально символ с индексом r не включен в окно)
right_char = s[r]
window_code[right_char] += 1
# Двигаем окно слева на право
l += 1
r += 1
# Т.к изначально символ с индексом r не включен в окно, нам надо проверить кодированные представления после цикла
if is_anagram(window_code, p_code):
res.append(l)
return res