关于trie的定义和图形请先看这里的简短描述。下面列出它相关的一些基本操作。
1. build a trie
这是基本操作,建立一个trie,add a word, search for that word, 正好有道题目在Leetcode上.
class TrieNode {
// Initialize your data structure here.
char element;
TrieNode[] child;
boolean isWord;
public TrieNode() {
element = '\0'; //这是JAVA的char的initialize的方式
child = new TrieNode[26];
isWord = false;
}
public TrieNode(char e) {
this.element = e;
child = new TrieNode[26];
isWord = false;
}
}
public class Trie {
private TrieNode root;
public Trie() {
root = new TrieNode();
}
// Inserts a word into the trie.
public void insert(String word) {
if (word == null){
return;
}
TrieNode current = root;
//error1:如果子node存在,不需要重新new新的子node,如果子node不存在,则new出一个。
// for (int i = 0; i < word.length(); ++i) {
// TrieNode newNode = new TrieNode(word.charAt(i));
// current.child[word.charAt(i) - 'a'] = newNode;
// current = newNode;
// }
for (int i = 0; i < word.length(); ++i) {
if (current.child[word.charAt(i) - 'a'] == null) {
current.child[word.charAt(i) - 'a'] = new TrieNode(word.charAt(i));
}
current = current.child[word.charAt(i) - 'a'];
}
current.isWord = true;
}
// Returns if the word is in the trie.
public boolean search(String word) {
if (word == null){
return false;
}
TrieNode current = root;
for (int i = 0; i < word.length(); ++i) {
char currentChar = word.charAt(i);
if (current.child[currentChar - 'a'] == null){
return false;
}
current = current.child[currentChar - 'a'];
}
return current.isWord;
}
// Returns if there is any word in the trie
// that starts with the given prefix.
public boolean startsWith(String prefix) {
if (prefix == null){
return false;
}
TrieNode current = root;
for (int i = 0; i < prefix.length(); ++i) {
char currentChar = prefix.charAt(i);
if (current.child[currentChar - 'a'] == null){
return false;
}
current = current.child[currentChar - 'a'];
}
return true;
}
}
另外,这并不是唯一正确的版本,就本题而言,element是不一定需要存在的field。但是对于别的题目而言,可能会根据需求使用element。
2. tell if a word is in a trie, if that might word has dots in it, where each dot symbol represent either character.
正好有一道题目Add and Search Word - Data structure design
class TrieNode {
// Initialize your data structure here.
char element;
TrieNode[] child;
boolean isWord;
public TrieNode() {
element = '\0'; //这是JAVA的char的initialize的方式
child = new TrieNode[26];
isWord = false;
}
public TrieNode(char e) {
this.element = e;
child = new TrieNode[26];
isWord = false;
}
}
public class WordDictionary {
private TrieNode root;
public WordDictionary() {
root = new TrieNode();
}
// Adds a word into the data structure.
public void addWord(String word) {
if (word == null){
return;
}
TrieNode current = root;
for (int i = 0; i < word.length(); ++i) {
if (current.child[word.charAt(i) - 'a'] == null) {
current.child[word.charAt(i) - 'a'] = new TrieNode(word.charAt(i));
}
current = current.child[word.charAt(i) - 'a'];
}
current.isWord = true;
}
// Returns if the word is in the data structure. A word could
// contain the dot character '.' to represent any one letter.
//基本思路: 沿着树走,看是否能够走完word的所有字母,如果走不下去就说明false,
//如果走完了,最后一步还要检查node.isWord.如果isWord = false,说明只是某个单词的前缀,
//找到了前缀并代表已经找到了word, 只有当isWord = true时,才说明找到了word.
private boolean dfs(TrieNode node, String word, int index) {
if (index == word.length()) {
return node.isWord;
}
char currentChar = word.charAt(index);
if (currentChar != '.' ) {
if (node.child[currentChar - 'a'] != null) {
return dfs(node.child[currentChar - 'a'], word, index + 1);
} else {
return false;
}
} else {
for ( int i = 0; i < 26; ++ i) {
if (node.child[i] != null && dfs(node.child[i], word, index + 1)){
return true;
}
}
return false;
}
}
public boolean search(String word) {
if (word == null){
return false;
}
return dfs(root, word, 0);
}
}
// Your WordDictionary object will be instantiated and called as such:
// WordDictionary wordDictionary = new WordDictionary();
// wordDictionary.addWord("word");
// wordDictionary.search("pattern");
3. one application of trie