字典树(前缀树)Trie是一种数据结构,用于高效的存储和检索字符串数据集中的键。应用场景:自动补充和拼写检查
Leetcode.208 实现前缀树 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 class Trie { private Trie[] children; private boolean isEnd; public Trie () { children = new Trie [26 ]; isEnd = false ; } public void insert (String word) { Trie node = this ; for (int i=0 ;i<word.length();i++) { char ch = word.charAt(i); int index = ch - 'a' ; if (node.children[index]==null ) { node.children[index] = new Trie (); } node = node.children[index]; } node.isEnd = true ; } public boolean search (String word) { Trie node = searchPrefix(word); return node != null && node.isEnd; } public boolean startsWith (String prefix) { return searchPrefix(prefix) != null ; } private Trie searchPrefix (String prefix) { Trie node = this ; for (int i=0 ;i<prefix.length();i++) { char ch = prefix.charAt(i); int index = ch - 'a' ; if (node.children[index]==null ) { return null ; } node = node.children[index]; } return node; } }
这里使用了Trie数组来存储子节点,也可以使用TreeMap来实现
Leetcode.720 字典中最长的单词 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 class Solution { public String longestWord (String[] words) { Trie trie = new Trie (); for (String word : words) { trie.insert(word); } String longest = "" ; for (String word : words) { if (trie.search(word)) { if (word.length() > longest.length() || (word.length() == longest.length() && word.compareTo(longest) < 0 )) { longest = word; } } } return longest; } } class Trie { Trie[] children; boolean isEnd; public Trie () { children = new Trie [26 ]; isEnd = false ; } public void insert (String word) { Trie node = this ; for (int i = 0 ; i < word.length(); i++) { char ch = word.charAt(i); int index = ch - 'a' ; if (node.children[index] == null ) { node.children[index] = new Trie (); } node = node.children[index]; } node.isEnd = true ; } public boolean search (String word) { Trie node = this ; for (int i = 0 ; i < word.length(); i++) { char ch = word.charAt(i); int index = ch - 'a' ; if (node.children[index] == null || !node.children[index].isEnd) { return false ; } node = node.children[index]; } return node != null && node.isEnd; } }
这题是对Trim的完美应用。精辟的在于search()函数中,一旦该字符串的节点路径上存在节点的isEnd属性为假,那么就将该字符串抛弃