题目:
实现一个 Trie (前缀树),包含 insert
, search
, 和 startsWith
这三个操作。
示例:
Trie trie = new Trie(); trie.insert("apple"); trie.search("apple"); // 返回 true trie.search("app"); // 返回 false trie.startsWith("app"); // 返回 true trie.insert("app"); trie.search("app"); // 返回 true
说明:
- 你可以假设所有的输入都是由小写字母
a-z
构成的。 - 保证所有输入均为非空字符串。
思路:
前缀树介绍和java实现:https://blog.csdn.net/coffee_dount/article/details/106095177
java代码:
class Trie {
private class Node {
private int dumpli_num;该字串的重复数目, 该属性统计重复次数的时候有用,取值为0、1、2、3、4、5……
private int prefix_num;///以该字串为前缀的字串数, 应该包括该字串本身!!!!!
private Node childs[];此处用数组实现,当然也可以map或list实现以节省空间
private boolean isLeaf;///是否为单词节点
public Node() {
dumpli_num = 0;
prefix_num = 0;
isLeaf = false;
childs = new Node[26];
}
}
private Node root;///树根
public Trie() {
///初始化trie 树
root = new Node();
}
/**
* 插入字串,用循环代替迭代实现
*
* @param words
*/
public void insert(String words) {
insert(this.root, words);
}
/**
* 插入字串,用循环代替迭代实现
*
* @param root
* @param words
*/
private void insert(Node root, String words) {
words = words.toLowerCase();转化为小写
char[] chrs = words.toCharArray();
for (int i = 0, length = chrs.length; i < length; i++) {
///用相对于a字母的值作为下标索引,也隐式地记录了该字母的值
int index = chrs[i] - 'a';
if (root.childs[index] != null) {
已经存在了,该子节点prefix_num++
root.childs[index].prefix_num++;
} else {
///如果不存在
root.childs[index] = new Node();
root.childs[index].prefix_num++;
}
///如果到了字串结尾,则做标记
if (i == length - 1) {
root.childs[index].isLeaf = true;
root.childs[index].dumpli_num++;
}
///root指向子节点,继续处理
root = root.childs[index];
}
}
/**
* 查询某字串是否在字典树中
*
* @param word
* @return true if exists ,otherwise false
*/
public boolean search(String word) {
char[] chs = word.toLowerCase().toCharArray();
Node tmpRoot = root;
for (int i = 0, length = chs.length; i < length; i++) {
int index = chs[i] - 'a';
if (tmpRoot.childs[index] == null) {
///如果不存在,则查找失败
return false;
}
tmpRoot = tmpRoot.childs[index];
}
// 不能有孩子了
return tmpRoot.isLeaf;
}
public boolean startsWith(String prefix) {
char[] chrs = prefix.toLowerCase().toCharArray();
Node tmpRoot = root;
for (int i = 0, length = chrs.length; i < length; i++) {
int index = chrs[i] - 'a';
if (tmpRoot.childs[index] == null) {
return false;
}
tmpRoot = tmpRoot.childs[index];
}
return true;
}
}
/**
* Your Trie object will be instantiated and called as such:
* Trie obj = new Trie();
* obj.insert(word);
* boolean param_2 = obj.search(word);
* boolean param_3 = obj.startsWith(prefix);
*/