Trie前缀树
转载自:https://leetcode-cn.com/problems/implement-trie-prefix-tree/ 原题
Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。
插入字符串
我们从字典树的根开始,插入字符串。对于当前字符对应的子节点,有两种情况:
- 子节点存在。沿着指针移动到子节点,继续处理下一个字符。
- 子节点不存在。创建一个新的子节点,记录在children 数组的对应位置上,然后沿着指针移动到子节点,继续搜索下一个字符。
重复以上步骤,直到处理字符串的最后一个字符,然后将当前节点标记为字符串的结尾。
查找前缀
我们从字典树的根开始,查找前缀。对于当前字符对应的子节点,有两种情况:
- 子节点存在。沿着指针移动到子节点,继续搜索下一个字符。
- 子节点不存在。说明字典树中不包含该前缀,返回空指针。
重复以上步骤,直到返回空指针或搜索完前缀的最后一个字符。
若搜索到了前缀的末尾,就说明字典树中存在该前缀。此外,若前缀末尾对应节点的isEnd为真,说明Trie中存在该string
代码
(原题用vector实现)
1 #include <iostream> 2 #include <map> 3 4 using namespace std; 5 6 class Trie{ 7 private: 8 map<char, Trie*> children; 9 bool isEnd; 10 11 Trie* searchPrefix(string prefix) { 12 Trie* node = this; 13 for (char ch: prefix) { 14 if (node->children[ch] == nullptr){ 15 return nullptr; 16 } 17 node = node->children[ch]; 18 } 19 return node; 20 } 21 public: 22 Trie():isEnd(false) {} 23 24 void insert(string word) { 25 Trie* node = this; 26 for (char ch: word) { 27 if (node->children.find(ch) == node->children.end()) { 28 node->children[ch] = new Trie(); 29 } 30 node = node->children[ch]; 31 } 32 node->isEnd = true; 33 } 34 35 bool search(string word) { 36 Trie* node = this->searchPrefix(word); 37 return node != nullptr && node->isEnd; 38 } 39 40 bool startsWith(string prefix) { 41 return this->searchPrefix(prefix) != nullptr; 42 } 43 }; 44 45 int main() 46 { 47 Trie t; 48 t.insert("hello"); 49 t.insert("hola"); 50 cout << boolalpha << t.search("hola") << endl; 51 }
字典树的应用:
例题:https://leetcode-cn.com/problems/word-search-ii/
给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words,找出所有同时在二维网格和字典中出现的单词。
单词必须按照字母顺序,通过 相邻的单元格 内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。
输入:board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words = ["oath","pea","eat","rain"]
输出:["eat","oath"]
实现:
1 from collections import defaultdict 2 3 4 class Trie: 5 def __init__(self): 6 self.children = defaultdict(Trie) 7 self.word = "" 8 9 def insert(self, word): 10 cur = self 11 for c in word: 12 cur = cur.children[c] 13 cur.is_word = True 14 cur.word = word 15 16 17 class Solution: 18 def findWords(self, board: List[List[str]], words: List[str]) -> List[str]: 19 trie = Trie() 20 for word in words: 21 trie.insert(word) 22 23 def dfs(now, i1, j1): 24 if board[i1][j1] not in now.children: 25 return 26 27 ch = board[i1][j1] 28 29 now = now.children[ch] 30 if now.word != "": 31 ans.add(now.word) 32 33 board[i1][j1] = "#" 34 for i2, j2 in [(i1 + 1, j1), (i1 - 1, j1), (i1, j1 + 1), (i1, j1 - 1)]: 35 if 0 <= i2 < m and 0 <= j2 < n: 36 dfs(now, i2, j2) 37 board[i1][j1] = ch 38 39 ans = set() 40 m, n = len(board), len(board[0]) 41 42 for i in range(m): 43 for j in range(n): 44 dfs(trie, i, j) 45 46 return list(ans)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具