Tire 字典树模板和算法总结
Trie(前缀树) 的模板应用.
维基百科: https://zh.wikipedia.org/zh-hans/Trie
使用下面的模板:dfs_search是通过按键搜索有效 单词的题。
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 | 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。
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 | 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 |
用最前面的模板:
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 | 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
用最笨的方法居然也给过了!!!
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 | 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。
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 | 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!
补充,屏幕按键弹出单词的题目,在公司工作级编程里遇到的一个算法题目:
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 | 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" ])) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
2019-03-27 Dropout, DropConnect ——一个对输出,一个对输入
2018-03-27 leetcode 404. Sum of Left Leaves
2018-03-27 leetcode 100. Same Tree
2018-03-27 leetcode 383. Ransom Note
2018-03-27 leetcode 122. Best Time to Buy and Sell Stock II
2018-03-27 leetcode 13. Roman to Integer
2018-03-27 python 判断是否为有效域名