-
Notifications
You must be signed in to change notification settings - Fork 0
/
2020-02-04.py
60 lines (48 loc) · 1.7 KB
/
2020-02-04.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
"""
Implement an autocomplete system. That is, given a query string `s` and a set of all possible query strings,
return all strings in the set that have `s` as a prefix.
For example, given the query string `de` and the set of strings `[dog, deer, deal]`, return `[deer, deal]`.
Hint: Try preprocessing the dictionary into a more efficient data structure to speed up queries.
"""
from typing import Dict
Map = Dict[str, Dict]
class UncompressedTrie:
def __init__(self):
self.trie: Map = {}
def add_all(self, words):
for word in words:
self.add(word)
def add(self, word: str):
trie_level = self.trie
for idx in range(len(word)):
if not word[idx] in trie_level:
trie_level[word[idx]]: Map = {}
trie_level = trie_level[word[idx]]
trie_level["*"] = {word: {}}
def find(self, prefix: str):
if not self.trie:
return set()
trie_level = self.trie
for idx in range(len(prefix)):
if not prefix[idx] in trie_level:
return set()
trie_level = trie_level[prefix[idx]]
# find all words under this sub-trie
result = set()
self._find(trie_level, result)
return result
def _find(self, trie: Map, result: set):
if not trie:
return
if '*' in trie:
for key in trie['*'].keys():
result.add(key)
for key in trie:
self._find(trie[key], result)
if __name__ == "__main__":
trie = UncompressedTrie()
trie.add("dog")
assert "dog" in trie.find("dog")
trie.add("deer")
trie.add("deal")
assert set(["deer", "deal"]).issubset(trie.find("de"))