字典树
即前缀树 Trie
使用Trie,查询效率与有多少条目无关,只与要查的字符串长度有关,时间复杂度为O(w) w为字符串长度
Trie中每个节点存的不是字符串,而是将字符串拆开,存每个字符
Java代码实现
public class Trie {
private class Node {
/**
* 到当前节点是否构成一个单词
*/
boolean isWord;
/**
* <下一层节点存的字符,这个字符所在节点 >
*/
HashMap<Character, Node> next;
public Node(boolean isWord) {
this.isWord = isWord;
next = new HashMap<>();
}
public Node() {
this(false);
}
}
/**
* 前缀树存了多少单词
*/
private int size;
private Node root;
public Trie() {
size = 0;
root = new Node();
}
public int getSize() {
return size;
}
/**
* 添加
*/
public void add(String word) {
Node cur = root;
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (cur.next.get(c) == null) {
cur.next.put(c, new Node());
}
//如果当前节点下一层已经有这个字符节点了,直接将cur挪到这个节点
cur = cur.next.get(c);
}
//此时cur来到了最后一个字符表示的节点
//判断这个节点表示单词之前是否已经存在
if (!cur.isWord) {
cur.isWord = true;
size++;
}
}
/**
* 查询
*/
public boolean isExist(String word) {
Node cur = root;
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (cur.next.get(c) == null) {
return false;
}
cur = cur.next.get(c);
}
return cur.isWord;
}
/**
* 前缀查询
*/
public boolean isPrefix(String prefix) {
Node cur = root;
for (int i = 0;i < prefix.length();i++) {
char c = prefix.charAt(i);
if (cur.next.get(c) == null) {
return false;
}
cur = cur.next.get(c);
}
return true;
}
}