实现支持通配符的字典树(Trie):解决单词匹配问题
一、问题描述
我们需要设计一个数据结构,支持以下功能:
- 添加新单词
- 搜索字符串是否与任何已添加的单词匹配,其中搜索字符串可能包含通配符
.
(表示任意字符)。
例如:
- 插入单词
apple
- 搜索
app
→ false - 搜索
app.
→ true
二、方法思路:字典树(Trie)
为什么选择字典树?
字典树是一种高效的树形结构,特别适合处理字符串的前缀匹配问题。其核心优势在于:
- 空间效率高:共享公共前缀,减少冗余存储。
- 时间复杂度低:插入和查询的时间复杂度均为 O(L)(L 为单词长度)。
- 天然支持前缀搜索,易于扩展通配符功能。
通配符 .
的处理逻辑
当搜索遇到 .
时,需要递归遍历当前节点的所有子节点。例如,搜索 app.
时,需检查所有以 app
开头的单词。
三、代码实现(Java)
class WordDictionary {
private TrieNode root;
public WordDictionary() {
root = new TrieNode();
}
public void addWord(String word) {
TrieNode node = root;
for (char c : word.toCharArray()) {
if (!node.containsKey(c)) {
node.put(c, new TrieNode());
}
node = node.get(c);
}
node.setEnd(); // 标记单词结束
}
public boolean search(String word) {
return searchHelper(word, 0, root);
}
private boolean searchHelper(String word, int index, TrieNode node) {
if (index == word.length()) {
return node.isEnd(); // 检查是否到达单词末尾
}
char c = word.charAt(index);
if (c == '.') {
// 遍历所有可能的子节点
for (char childChar = 'a'; childChar <= 'z'; childChar++) {
if (node.containsKey(childChar) &&
searchHelper(word, index + 1, node.get(childChar))) {
return true;
}
}
return false;
} else {
// 常规字符匹配
return node.containsKey(c) &&
searchHelper(word, index + 1, node.get(c));
}
}
class TrieNode {
private TrieNode[] children = new TrieNode[26];
private boolean isEnd;
public boolean.containsKey(char c) {
return children[c - 'a'] != null;
}
public TrieNode get(char c) {
return children[c - 'a'];
}
public void put(char c, TrieNode node) {
children[c - 'a'] = node;
}
public void setEnd() {
isEnd = true;
}
public boolean isEnd() {
return isEnd;
}
}
}
四、代码解析
1. TrieNode 类
- children 数组:存储 26 个字母对应的子节点。
- isEnd 标记:表示该节点是否是单词的结尾。
2. addWord 方法
- 逐个字符遍历单词,构建字典树结构。
- 到达单词末尾时,标记
isEnd
为true
。
3. search 方法
- 递归搜索:从根节点开始,逐个字符匹配。
- 通配符处理:当遇到
.
时,遍历所有可能的子节点。 - 终止条件:当遍历完所有字符时,检查当前节点是否为单词结尾。
五、复杂度分析
操作 | 时间复杂度 | 空间复杂度 |
---|---|---|
插入单词 | O(L) | O(L) |
搜索单词 | O(L * 26^k) | O (1)(递归栈空间) |
- L:单词长度。
- k:搜索字符串中
.
的数量。
六、示例说明
测试用例:
WordDictionary dict = new WordDictionary();
dict.addWord("apple");
dict.addWord("app");
dict.search("app"); // true
dict.search("app."); // true(匹配 "apple" 或 "app")
dict.search("ap.."); // true(匹配 "apple")
dict.search("apx."); // false
七、总结
字典树是解决字符串匹配问题的高效工具,结合递归处理通配符,可以优雅地实现本题要求。这种方法在需要频繁进行插入和搜索操作的场景下表现优异,例如拼写检查、自动补全等。