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)
复制代码

 

posted @   Asp1rant  阅读(67)  评论(0编辑  收藏  举报
编辑推荐:
· 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工具
点击右上角即可分享
微信分享提示