字典树(Trie)用于判断字符串是否存在或者是否具有某种字符串前缀。
字典树
为什么需要用字典树解决这类问题呢?假如我们有一个储存了近万个单词的字典,即使我们使用哈希,在其中搜索一个单词的实际开销也是非常大的,且无法轻易支持搜索单词前缀。然而 由于一个英文单词的长度 n 通常在 10 以内,如果我们使用字典树,则可以在 O(n)——近似 O(1) 的时间内完成搜索,且额外开销非常小。
构建字典树
尝试建立一个字典树,支持快速插入单词、查找单词、查找单词前缀的功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
|
public class Trie { TrieNode root; public Trie(){ root=new TrieNode(); } public void insert(String word){ TrieNode tmp=root; for(int i=0;i<word.length();i++){ if(null == tmp.childNode[word.charAt(i) - 'a']){ tmp.childNode[word.charAt(i)-'a']=new TrieNode(); } tmp=tmp.childNode[word.charAt(i)-'a']; } tmp.isVal=true; } boolean search(String word){ TrieNode tmp=root; for(int i=0;i<word.length();++i){ if(tmp==null){ break; } tmp=tmp.childNode[word.charAt(i)-'a']; } return tmp!=null?tmp.isVal:false; } boolean startsWith(String prefix){ TrieNode tmp=root; for(int i=0;i<prefix.length();i++){ if(tmp==null){ break; } tmp=tmp.childNode[prefix.charAt(i)-'a']; } return tmp!=null; }
public static void main(String[] args) { Trie trie=new Trie(); System.out.println(trie.search("apple")); trie.insert("apple"); System.out.println(trie.search("apple")); System.out.println(trie.search("app")); System.out.println(trie.startsWith("app")); trie.insert("app"); System.out.println(trie.search("app"));
} }
class TrieNode{ TrieNode[] childNode =new TrieNode[26]; boolean isVal; TrieNode(){ isVal=false; for(int i=0;i<26;i++){ childNode[i]=null; } } }
|