Trie即前缀树或字典树,利用字符串公共前缀降低搜索时间。速度为O(k),k为输入的字符串长度。
1.采用defaultdict创建trie
from collections import defaultdict from functools import reduce TrieNode = lambda: defaultdict(TrieNode) class Trie: def __init__(self): self.trie = TrieNode() def insert(self, word): reduce(dict.__getitem__, word, self.trie)['end'] = True def search(self, word): return reduce(lambda d,k: d[k] if k in d else TrieNode(), word, self.trie).get('end', False) def startsWith(self, word): return bool(reduce(lambda d,k: d[k] if k in d else TrieNode(), word, self.trie).keys())
2.采用dictionary结构
#定义trie结构体
class TrieNode(object): def __init__(self): """ Initialize your data structure here. """ self.data = {} self.is_word = False class Trie(object): def __init__(self): self.root = TrieNode() def insert(self, word): """ Inserts a word into the trie. :type word: str :rtype: void """ node = self.root for letter in word: child = node.data.get(letter) if not child: node.data[letter] = TrieNode() node = node.data[letter] node.is_word = True def search(self, word): """ Returns if the word is in the trie. :type word: str :rtype: bool """ node = self.root for letter in word: node = node.data.get(letter) if not node: return False return node.is_word # 判断单词是否是完整的存在在trie树中 def starts_with(self, prefix): """ Returns if there is any word in the trie that starts with the given prefix. :type prefix: str :rtype: bool """ node = self.root for letter in prefix: node = node.data.get(letter) if not node: return False return True def get_start(self, prefix): """ Returns words started with prefix :param prefix: :return: words (list) """ def _get_key(pre, pre_node): words_list = [] if pre_node.is_word: words_list.append(pre) for x in pre_node.data.keys(): words_list.extend(_get_key(pre + str(x), pre_node.data.get(x))) return words_list words = [] if not self.starts_with(prefix): return words if self.search(prefix): words.append(prefix) return words node = self.root for letter in prefix: node = node.data.get(letter) return _get_key(prefix, node)