huahua讲得太好了, 感觉今天才懂trie到底是个啥。
https://www.youtube.com/watch?v=8d_HdK0f2B4
关键点
- root是空的,可以类比链表里的dummy node
- 每个node的children都被初始化为一个TrieNode[26], 依次用来储存a, b, c, d, 一开始我一直不明白我到了这个node怎么知道这个地方的word到底是什么,但实际上因为这个顺序的关系,你到的是哪一个index的位置,自然就知道单词了。比如1 - 2 - 3肯定对应的就是 bcd这个单词,所以不需要另外写方法去记录。
- insert和find写得其实很类似,都是先用p = root, 然后一个字符一个字符地traverse, 看对应的index是否为null. insert的时候如果遇到null就new,然后不再null,继续traverse.如果是find遇到null说明这个词不存在!
class Trie {
class TrieNode{
TrieNode[] children;
boolean isWord;
public TrieNode(){
this.children = new TrieNode[26];
this.isWord = false;
}
}
TrieNode root;
/** Initialize your data structure here. */
public Trie() {
this.root = new TrieNode();
}
/** Inserts a word into the trie. */
public void insert(String word) {
TrieNode p = root;
for (int i = 0; i < word.length(); i++){
int index = word.charAt(i) - 'a';
if (p.children[index] == null){
p.children[index] = new TrieNode();
}
p = p.children[index];
}
p.isWord = true;
}
/** Returns if the word is in the trie. */
public boolean search(String word) {
return find(word) != null && find(word).isWord;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
public boolean startsWith(String prefix) {
return find(prefix) != null;
}
private TrieNode find(String s){
TrieNode p = root;
for (int i = 0; i < s.length(); i++){
int index = s.charAt(i) - 'a';
p = p.children[index];
if (p == null){
break;
}
}
return p;
}
}
/**
* 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);
*/
网友评论