概述
前缀树又称字典树,是一种N叉树的数据结构,如下图所示:
要求
- 实现前缀树
- insert(String word),插入单词
- search(String word),搜索单词
- startWith(String prefix),搜索前缀
分析
- 插入单词的过程即构建前缀树的过程
- 搜索单词
- 如果被搜索字符串不在前缀树中,返回false
- 如果在前缀树中,还需判断是否是单词,如上图示例中:搜索at返回true,搜索a返回false
- 搜索前缀,被搜索的字符串在前缀树中返回true,否则返回false
代码解析
/** 前缀树(字典树) */
public class Trie {
/** 节点类 */
class Node {
Map<Character, Node> children = new HashMap<>();
// 是否单词
boolean isWord;
}
/** 前缀树的根节点 */
private Node root;
public Trie() {
root = new Node();
}
/**
* 插入单词,构建前缀树
*
* @param word
*/
public void insert(String word) {
Node node = root;
char[] chars = word.toCharArray();
// 遍历单词的每一个字母
for (int i = 0; i < chars.length; i++) {
// 如果前缀树中没有当前字母,则插入
if (!node.children.containsKey(chars[i])) node.children.put(chars[i], new Node());
// 指向当前节点,继续遍历
node = node.children.get(chars[i]);
}
// 标记为单词
node.isWord = true;
}
/**
* 搜索单词
*
* @param word
* @return
*/
public boolean search(String word) {
return search(word, true);
}
/**
* 搜索前缀
*
* @param prefix
* @return
*/
public boolean startsWith(String prefix) {
return search(prefix, false);
}
/**
* 搜索单词(前缀)
*
* @param word 单词(前缀)字符串
* @param isWord 是否单词,true:查找单词,false:查找前缀
* @return
*/
private boolean search(String word, boolean isWord) {
Node node = root;
char[] chars = word.toCharArray();
for (int i = 0; i < chars.length; i++) {
// 如果当前字母不在前缀树中,则查找不到此单词(前缀)
if (!node.children.containsKey(chars[i])) return false;
// 指向当前节点,继续遍历
node = node.children.get(chars[i]);
}
return isWord ? node.isWord : true;
}
/**
* 测试
*
* @param args
*/
public static void main(String[] args) {
Trie trie = new Trie();
trie.insert("bee");
System.out.println(trie.search("bee"));
System.out.println(trie.search("be"));
System.out.println(trie.startsWith("b"));
System.out.println(trie.startsWith("ba"));
}
}
总结
前缀树是一种具有特定规则的N叉树,即使在不熟悉前缀树概念的前提下,我们也可以根据题目中给出的条件及图例分析并完成代码。