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
| from collections import defaultdict
class RadixTreeNode(): def __init__(self, is_word=False, keys=None): self.is_word = is_word self.children = keys if keys else defaultdict(RadixTreeNode)
class Trie(): def __init__(self): self.root = RadixTreeNode()
def insert(self, word): return self.insert_helper(self.root, word)
def insert_helper(self, node, word): for key, child in node.children.items(): prefix, split, rest = self.match(key, word) if not split: if not rest: child.is_word = True return True else: return self.insert_helper(child, rest) if prefix: new_node = RadixTreeNode(is_word=not rest, keys={split: child}) node.children[prefix] = new_node del node.children[key] return self.insert_helper(new_node, rest) node.children[word] = RadixTreeNode(is_word=True)
def search(self, word): return self.search_helper(self.root, word)
def search_helper(self, node, word): for key, child in node.children.items(): prefix, split, rest = self.match(key, word) if not split and not rest: return child.is_word if not split: return self.search_helper(child, rest) return False
def startsWith(self, word): return self.startsWith_helper(self.root, word)
def startsWith_helper(self, node, word): for key, child in node.children.items(): prefix, split, rest = self.match(key, word) if not rest: return True if not split: return self.startsWith_helper(child, rest) return False
def match(self, key, word): i = 0 for k, w in zip(key, word): if k != w: break i += 1 return key[:i], key[i:], word[i:]
|