题意
Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。
请你实现 Trie 类:
Trie() 初始化前缀树对象。
void insert(String word) 向前缀树中插入字符串 word。
boolean search(String word) 如果字符串 word 在前缀树中,返回 true(即,在检索之前已经插入);否则,返回 false。
boolean startsWith(String prefix) 如果之前已经插入的字符串 word 的前缀之一为 prefix,返回 true;否则,返回 false。
分析
前缀树是一种树形结构,其将一个字符串表示在一棵树中,例如:
绘图1.png
其中保存了数据【APP、APPLE、TIRE】其中,黄色节点表示含有这个对象,蓝色表示只是路径节点。
注意:前缀树是有一个总的虚拟头节点。
题解
// 定义节点结构
class TireNode {
char value;// 当前节点的值
boolean isExists = false;// 当前节点是都被包含【上述黄色节点】
HashMap<Character, TireNode> children = new HashMap<Character, TireNode>();//【具体的分支】
public TireNode(char value) {
this.value = value;
}
}
// 实现前缀树
class Trie {
// 虚拟头节点
TireNode dummyHead = new TireNode('-');
public void insert(String word) {
// 处理特殊情况
if (word == null || word.length() == 0) return;
// 是否需要创建根节点
insertSub(word, 0, dummyHead.children);
}
// 将指定元素插入前缀树的指定位置
public void insertSub(String word, int start, HashMap<Character, TireNode> children) {
// 插入到元素末尾,直接返回
if (start == word.length()) return;
if (children.containsKey(word.charAt(start))) {
TireNode tireNodeTemp = children.get(word.charAt(start));
// 判断是否存在当前元素
if (start == word.length() - 1) tireNodeTemp.isExists = true;
insertSub(word, start + 1, tireNodeTemp.children);
// 不包含当前节点
} else {
TireNode node = new TireNode(word.charAt(start));
// 判断是否存在当前元素
if (start == word.length() - 1) node.isExists = true;
children.put(word.charAt(start), node);
// 插入元素
insertSub(word, start + 1, node.children);
}
}
// 查找特定字符串
public boolean search(String word) {
TireNode tireNodeResult = searchSub(word, 0, dummyHead.children.get(word.charAt(0)));
if (tireNodeResult == null) return false;
return tireNodeResult.isExists;
}
public TireNode searchSub(String word, int start, TireNode tireNode) {
if (tireNode == null) return null;
if (tireNode.value == word.charAt(start)) {
if (start == word.length() - 1) return tireNode;
// 寻找下一个字符
if (start + 1 < word.length())
return searchSub(word, start + 1, tireNode.children.get(word.charAt(start + 1)));
}
return null;
}
// 是否有前缀
public boolean startsWith(String prefix) {
TireNode tireNodeResult = searchSub(prefix, 0, dummyHead.children.get(prefix.charAt(0)));
if (tireNodeResult == null) return false;
return true;
}
}
网友评论