字典树
字典树(Trie),又称前缀树,是一种用于快速检索字符串集合中键的多叉树结构。
核心思想
Trie 利用字符串的 公共前缀 来减少查询时间,最大限度地减少无谓的字符串比较。
结构特点
- 根节点不包含字符,除根节点外每一个节点都只包含一个字符。
- 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
- 每个节点的所有子节点包含的字符都不相同。
实现细节
每个节点通常包含:
- 一个子节点数组(通常大小为 26,对应 a-z)。
- 一个布尔值
isEnd,标识该节点是否为一个单词的结尾。
class TrieNode {
TrieNode[] children = new TrieNode[26];
boolean isEnd = false;
}
public class Trie {
private TrieNode root;
public Trie() {
root = new TrieNode();
}
// 插入单词 - O(L) L为单词长度
public void insert(String word) {
TrieNode node = root;
for (char c : word.toCharArray()) {
int index = c - 'a';
if (node.children[index] == null) {
node.children[index] = new TrieNode();
}
node.set(node.children[index]);
node = node.children[index];
}
node.isEnd = true;
}
// 搜索单词 - O(L)
public boolean search(String word) {
TrieNode node = find(word);
return node != null && node.isEnd;
}
// 检查是否有以 prefix 开头的单词 - O(L)
public boolean startsWith(String prefix) {
return find(prefix) != null;
}
private TrieNode find(String s) {
TrieNode node = root;
for (char c : s.toCharArray()) {
int index = c - 'a';
if (node.children[index] == null) return null;
node = node.children[index];
}
return node;
}
}
应用场景
- 自动补全 / 搜索建议。
- 拼写检查。
- 前缀匹配。
- 最长公共前缀。
练习
- LeetCode 208:实现 Trie (前缀树)
- LeetCode 211:添加与搜索单词 - 数据结构设计
- LeetCode 677:键值映射 (Map Sum Pairs)
- LeetCode 648:单词替换