字典树的结构图:
字典树有三个特点:
1、根节点不包含字符,除根节点外每一个节点都只包含一个字符
2、 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串
3、每个节点的所有子节点包含的字符都不相同
首先定义字典树的节点:
Class Node {
boolean isWord;
Map<Character, Node> next;
}
isWord标识从根节点到当前节点组成的字符串是不是一个单词
每个节点维护了一个Map,根据字符可以找到下一个Node
public class Trie {
class Node {
boolean isWord;
Map<Character, Node> next;
Node() {
isWord = false;
next = new HashMap<>();
}
boolean containsKey(char key) {
return next.containsKey(key);
}
void put(char key) {
if (!next.containsKey(key)) {
next.put(key, new Node());
}
}
Node get(char key) {
return next.get(key);
}
boolean isWord() {
return isWord;
}
void setIsWord() {
isWord = true;
}
}
private Node root;
/** Initialize your data structure here. */
public Trie() {
root = new Node();
}
/** Inserts a word into the trie. */
public void insert(String word) {
Node current = root;
char[] chs = word.toCharArray();
for (int i = 0; i < chs.length; i++) {
if (!current.containsKey(chs[i])) {
current.put(chs[i]);
}
current = current.get(chs[i]);
}
current.setIsWord();
}
/** Returns if the word is in the trie. */
public boolean search(String word) {
Node node = searchPre(word);
return node == null ? false : node.isWord;
}
/**
* Returns if there is any word in the trie that starts with the given
* prefix.
*/
public boolean startsWith(String prefix) {
return searchPre(prefix) != null;
}
private Node searchPre(String word) {
Node current = root;
char[] chs = word.toCharArray();
for (int i = 0; i < chs.length; i++) {
if (current.containsKey(chs[i])) {
current = current.get(chs[i]);
} else {
return null;
}
}
return current;
}
}
由于题目中给出可以假设所有输入中只包含小写a-z的字符,所以可以使用数组来替代Map,ch - 'a'即是数组的下标