Trie,又稱前綴樹或字典樹,用於判斷字符串是否存在或者是否具有某種字符串前綴。
實現 Trie (前綴樹)
https://leetcode-cn.com/problems/implement-trie-prefix-tree/
二叉樹的每個節點存放兩個指針,left指向左子樹的頭結點,right指向了右子樹的頭結點,這兩個指針都爲Node類型;
相對於二叉樹,前綴樹的節點也要存指針,指向其他子節點。那麼對於這種類型的指針該如何設計呢,如果是要設計與字符串相關的前綴樹(假設字符的範圍爲a-z),Node類中只需要維護一個指針數組,大小爲26(對應26個英文字母),該數組也是Node類型,用來子節點的指針,很明顯,前綴樹是一個多叉樹。
除了指針外,還要維護一個類型爲boolean的變量,來判斷節點是否爲葉子節點。
那麼對於前綴樹的insert方法來說,不需要真正的插入字符串每個字符的值,只需要在每個節點中將字符所對應下標的位置上插入一個新的節點,就可以表示存在該字符,在前綴樹表示的字符串最後的一個字符中,要將isLeaf變量設爲true,表示字符串到此結束。
對於search方法來說,逐一判斷前綴樹中是否存在字符串的所有字符即可,如果前綴樹中所對應字符串指定字符的節點爲null,那麼表示不存在該字符串,直到判斷字符串的最後一個字符,並判斷isLeaf是否爲true。(表示字符串結束)
對於startsWith方法來說,逐一判斷前綴樹中是否存在字符串的所有字符即可,如果前綴樹中所對應字符串指定字符的節點爲null,那麼表示不存在該字符串,直到判斷字符串的最後一個字符即可。無需判斷isLeaf。
class Trie {
private class Node{
Node[] childs = new Node[26];
boolean isLeaf;
}
private Node root = new Node();
/** Initialize your data structure here. */
public Trie() {}
/** Inserts a word into the trie. */
public void insert(String word) {
insert(word,root);
}
private void insert(String word,Node node) {
if(node == null) return;
if(word.length() == 0) {
node.isLeaf = true;
return;
}
int index = findCharIndex(word.charAt(0));
if(node.childs[index] == null)
node.childs[index] = new Node();
insert(word.substring(1),node.childs[index]);
}
/** Returns if the word is in the trie. */
public boolean search(String word) {
return search(word,root);
}
private boolean search(String word,Node node) {
if(node == null) return false;
if(word.length() == 0) return node.isLeaf;
int index = findCharIndex(word.charAt(0));
return search(word.substring(1),node.childs[index]);
}
/** Returns if there is any word in the trie that starts with the given prefix. */
public boolean startsWith(String prefix) {
return startsWith(prefix,root);
}
private boolean startsWith(String prefix,Node node) {
if(node == null) return false;
if(prefix.length() == 0) return true;
int index = findCharIndex(prefix.charAt(0));
return startsWith(prefix.substring(1),node.childs[index]);
}
//找到指定字符在節點中的index
private int findCharIndex(char c) {
return c - 'a';
}
}
/**
* 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);
*/