Implement a trie with insert
, search
, and startsWith
methods.
Note:
You may assume that all inputs are consist of lowercase letters a-z
solution:
class TrieNode { // Initialize your data structure here. boolean isEnd; //是否有单词以该字母结尾 TrieNode[] sons; //子节点[a-z] char value; //保存该节点代表的字母值 public TrieNode() { isEnd = false; sons = new TrieNode[26]; } } public class Trie { private TrieNode root; public Trie() { root = new TrieNode(); } // Inserts a word into the trie. /** * 对于传入的单词,从左往右遍历每个字母,依次从根节点向下建树 * 每个节点保存一个字母 * @param word */ public void insert(String word) { if (word == null || word.length() == 0) return; TrieNode p = root; //工作指针,初始指向根节点 for (int i = 0; i < word.length(); i++) { int pos = word.charAt(i) - 'a'; //hash-计算该字母对应的位置 if (p.sons[pos] == null) { //判断该位置是否为空 p.sons[pos] = new TrieNode(); p.sons[pos].value = word.charAt(i); } p = p.sons[pos]; //指向子节点 } p.isEnd = true; //标记该节点,表示有单词以之结尾 } // Returns if the word is in the trie. /** * 类似建树过程,从左往右简历单词的每个字母,如果对应位置为空,则表示树中 * 不存在该单词 * @param word * @return */ public boolean search(String word) { if (word == null || word.length() == 0) return false; TrieNode p = root; for (int i = 0; i < word.length(); i++) { int pos = word.charAt(i) - 'a'; if (p.sons[pos] == null) return false; p = p.sons[pos]; } return p.isEnd; //false表示所查单词是树中某个单词的前缀,但不完全匹配 } // Returns if there is any word in the trie // that starts with the given prefix. public boolean startsWith(String prefix) { if (prefix == null || prefix.length() == 0) return false; TrieNode p = root; for (int i = 0; i < prefix.length(); i++) { int pos = prefix.charAt(i) - 'a'; if (p.sons[pos] == null) return false; p = p.sons[pos]; } return true; } } // Your Trie object will be instantiated and called as such: // Trie trie = new Trie(); // trie.insert("somestring"); // trie.search("key");
Add and Search Word
Design a data structure that supports the following two operations:
void addWord(word)
bool search(word)
search(word) can search a literal word or a regular expression string containing only letters a-z
or .
. A .
means it can represent any one letter.
For example:
addWord("bad")
addWord("dad")
addWord("mad")
search("pad") -> false
search("bad") -> true
search(".ad") -> true
search("b..") -> true
Note:
You may assume that all words are consist of lowercase letters a-z
.
solution:
public class WordDictionary { private Tode root; public WordDictionary() { root = new Tode(); } // Adds a word into the data structure. /** * 与上题一致 * @param word */ public void addWord(String word) { if(word == null || word.length() == 0) return ; Tode p = root; for(int i=0; i<word.length(); i++){ int pos = word.charAt(i) - 'a'; if(p.sons[pos] == null){ p.sons[pos] = new Tode(); p.sons[pos].value = word.charAt(i); } p = p.sons[pos]; } p.isEnd = true; } // Returns if the word is in the data structure. A word could // contain the dot character '.' to represent any one letter. /** * 因为.能匹配所有字母,导致不能直接hash判断字母是否存在,而必须对树进行深度优先遍历。 * @param word * @return */ public boolean search(String word) { if(word == null || word.length() == 0) return false; char[] arr = word.toCharArray(); int index = 0; Tode p = root; return goSearch(arr, index, p); } private boolean goSearch(char[] arr, int index, Tode p) { if(index == arr.length) return p.isEnd; if(arr[index] == '.'){ for(Tode n : p.sons){ //搜索当前节点的所有非空子节点 if(n != null && goSearch(arr, index+1, n)) //若有节点搜索到匹配单词,则直接返回 return true; } return false; }else{ int pos = arr[index] - 'a'; if(p.sons[pos] != null) return goSearch(arr, index+1, p.sons[pos]); else return false; } } class Tode{ boolean isEnd; Tode[] sons; char value; public Tode(){ isEnd = false; sons = new Tode[26]; } } } // Your WordDictionary object will be instantiated and called as such: // WordDictionary wordDictionary = new WordDictionary(); // wordDictionary.addWord("word"); // wordDictionary.search("pattern");