Tire 字典树模板和算法总结
Trie(前缀树) 的模板应用.
维基百科: https://zh.wikipedia.org/zh-hans/Trie
使用下面的模板:dfs_search是通过按键搜索有效 单词的题。
from collections import defaultdict class Trie: def __init__(self): self.children = defaultdict(Trie) self.is_word = False self.word = "" def insert(self, word): if not word: return node = self for ch in word: node = node.children[ch] node.is_word = True node.word = word def find(self, word): node = self for c in word: if c not in node.children: return None node = node.children[c] return node def search(self, word): node = self.find(word) return node is not None and node.is_word def starts_with(self, prefix): return self.find(prefix) is not None def dfs_search(self, num_str, mapping): self.ans = 0 self.dfs(self, num_str, mapping, layer=0) return self.ans def dfs(self, node, nums, mapping, layer): if layer == len(nums): if node.is_word: self.ans += 1 print("found valid word:", node.word) return if not node.children: return for ch in mapping[nums[layer]]: if ch in node.children: self.dfs(node.children[ch], nums, mapping, layer+1) class Solution: def get_valid_words_num(self, num_str: str, word_list): mapping = {"2": "abc", "3": "def", "4": "ghi", "5": "jkl", "6": "mno", "7": "pqrs", "8": "tuv", "9": "wxyz"} trie = Trie() for word in word_list: trie.insert(word) print(trie.search("tree")) # True print(trie.search("used")) # True print(trie.search("whatever")) # False print(trie.starts_with("tre")) # True print(trie.starts_with("use")) # True return trie.dfs_search(num_str, mapping) print(Solution().get_valid_words_num("8733", ["tree", "used", "tere"]))
class TrieNode:
def __init__(self):
self.children = {}
self.is_word = False
class Trie:
def __init__(self):
self.root = TrieNode()
"""
@param: word: a word
@return: nothing
"""
def insert(self, word):
node = self.root
for c in word:
if c not in node.children:
node.children[c] = TrieNode()
node = node.children[c]
node.is_word = True
"""
return the node in the trie if exists
"""
def find(self, word):
node = self.root
for c in word:
node = node.children.get(c)
if node is None:
return None
return node
"""
@param: word: A string
@return: if the word is in the trie.
"""
def search(self, word):
node = self.find(word)
return node is not None and node.is_word
"""
@param: prefix: A string
@return: if there is any word in the trie that starts with the given prefix.
"""
def startsWith(self, prefix):
return self.find(prefix) is not None
这个实现更加简洁!!!我自己只是已经习惯自己的trie node里加入char word和children了!!!
442. 实现 Trie(前缀树)
中文
English
实现一个 Trie,包含 insert
, search
, 和 startsWith
这三个方法。
样例
样例 1:
输入:
insert("lintcode")
search("lint")
startsWith("lint")
输出:
false
true
样例 2:
输入:
insert("lintcode")
search("code")
startsWith("lint")
startsWith("linterror")
insert("linterror")
search("lintcode”)
startsWith("linterror")
输出:
false
true
false
true
true
注意事项
你可以认为所有的输入都是小写字母a-z。
class Node: def __init__(self, char="", word=""): self.char = char self.word = word self.children = {} class Trie: def __init__(self): # do intialization if necessary self.root = Node() """ @param: word: a word @return: nothing """ def insert(self, word): # write your code here node = self.root for w in word: if w not in node.children: node.children[w] = Node(char=w) node = node.children[w] node.word = word """ @param: word: A string @return: if the word is in the trie. """ def search(self, word): # write your code here node = self.root for w in word: if w not in node.children: return False node = node.children[w] return True if node.word == word else False """ @param: prefix: A string @return: if there is any word in the trie that starts with the given prefix. """ def startsWith(self, prefix): # write your code here node = self.root for w in prefix: if w not in node.children: return False node = node.children[w] return True
用最前面的模板:
class Node: def __init__(self): self.is_word = False self.children = {} class Trie: def __init__(self): # do intialization if necessary self.root = Node() """ @param: word: a word @return: nothing """ def insert(self, word): # write your code here node = self.root for w in word: if w not in node.children: node.children[w] = Node() node = node.children[w] node.is_word = True """ @param: word: A string @return: if the word is in the trie. """ def search(self, word): # write your code here assert word node = self.find(word) return node is not None and node.is_word def find(self, word): node = self.root for w in word: if w not in node.children: return None node = node.children[w] return node """ @param: prefix: A string @return: if there is any word in the trie that starts with the given prefix. """ def startsWith(self, prefix): # write your code here assert prefix node = self.find(prefix) return node is not None
出错曾 西部ƒ˙qgv
648. 单词替换
难度中等
在英语中,我们有一个叫做 词根
(root)的概念,它可以跟着其他一些词组成另一个较长的单词——我们称这个词为 继承词
(successor)。例如,词根an
,跟随着单词 other
(其他),可以形成新的单词 another
(另一个)。
现在,给定一个由许多词根组成的词典和一个句子。你需要将句子中的所有继承词
用词根
替换掉。如果继承词
有许多可以形成它的词根
,则用最短的词根替换它。
你需要输出替换之后的句子。
示例 1:
输入: dict(词典) = ["cat", "bat", "rat"] sentence(句子) = "the cattle was rattled by the battery" 输出: "the cat was rat by the bat"
注:
- 输入只包含小写字母。
- 1 <= 字典单词数 <=1000
- 1 <= 句中词语数 <= 1000
- 1 <= 词根长度 <= 100
- 1 <= 句中词语长度 <= 1000
用最笨的方法居然也给过了!!!
class Solution(object): def replaceWords(self, dict, sentence): """ :type dict: List[str] :type sentence: str :rtype: str """ trie = Trie() for w in dict: trie.add_word(w) words = sentence.split() return " ".join([trie.find_neareast(word) for word in words]) """ dict2 = {w for w in dict} words = sentence.split() return " ".join([self.replace(word, dict2) for word in words]) """ def replace(self, word, dict2): for i in range(1, len(word)+1): if word[:i] in dict2: return word[:i] return word class Node(object): def __init__(self, char="", word=""): self.char = char self.word = word self.children = {} class Trie(object): def __init__(self): self.root = Node() def add_word(self, word): cur = self.root for w in word: if w not in cur.children: cur.children[w] = Node(w) cur = cur.children[w] cur.word= word def find_neareast(self, word): cur = self.root for w in word: if cur.word: return cur.word if w not in cur.children: return word cur = cur.children[w] return word
473. 单词的添加与查找
中文
English
设计一个包含下面两个操作的数据结构:addWord(word)
, search(word)
addWord(word)
会在数据结构中添加一个单词。而search(word)
则支持普通的单词查询或是只包含.
和a-z
的简易正则表达式的查询。
一个 .
可以代表一个任何的字母。
样例
样例 1:
输入:
addWord("a")
search(".")
输出:
true
样例 2:
输入:
addWord("bad")
addWord("dad")
addWord("mad")
search("pad")
search("bad")
search(".ad")
search("b..")
输出:
false
true
true
true
注意事项
你可以认为所有的单词都只包含小写字母 a-z。
class Node: def __init__(self): self.is_word = False self.children = {} class Trie: def __init__(self): self.root = Node() def insert(self, word): node = self.root for ch in word: if ch not in node.children: node.children[ch] = Node() node = node.children[ch] node.is_word = True def search(self, word): return self.dfs(self.root, word, i=0) def dfs(self, node, word, i): if node is None: return False if i == len(word): return node.is_word if word[i] == '.': for c in node.children: if self.dfs(node.children[c], word, i + 1): return True return False else: if word[i] not in node.children: return False return self.dfs(node.children[word[i]], word, i + 1) class WordDictionary: def __init__(self): self.trie = Trie() def addWord(self, word): # write your code here self.trie.insert(word) """ @param: word: A word could contain the dot character '.' to represent any one letter. @return: if the word is in the data structure. """ def search(self, word): # write your code here return self.trie.search(word)
无非就是在Trie基础上加了DFS!
补充,屏幕按键弹出单词的题目,在公司工作级编程里遇到的一个算法题目:
class Node: def __init__(self, val=None): self.val = val self.is_word = False self.children = dict() class Trie: def __init__(self): self.root = Node() def insert(self, word): if not word: return node = self.root leaf = None for ch in word: if ch in node.children: node = node.children[ch] else: node.children[ch] = Node(ch) node = node.children[ch] leaf = node leaf.is_word = True def search(self, num_str, mapping): self.ans = 0 self.dfs(self.root, num_str, mapping, layer=0) return self.ans def dfs(self, node, nums, mapping, layer): if layer == len(nums): if node.is_word: self.ans += 1 return if not node.children: return for ch in mapping[nums[layer]]: if ch in node.children: self.dfs(node.children[ch], nums, mapping, layer+1) class Solution: def get_valid_words_num(self, num_str: str, word_list): mapping = {"2": "abc", "3": "def", "4": "ghi", "5": "jkl", "6": "mno", "7": "pqrs", "8": "tuv", "9": "wxyz"} trie = Trie() for word in word_list: trie.insert(word) return trie.search(num_str, mapping) print(Solution().get_valid_words_num("8733", ["tree", "used", "tere"])) print(Solution().get_valid_words_num("2", ["a", "b", "c", "d"]))