Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。
请你实现 Trie 类:
Trie()
初始化前缀树对象。void insert(String word)
向前缀树中插入字符串word
。boolean search(String word)
如果字符串word
在前缀树中,返回true
(即,在检索之前已经插入);否则,返回false
。boolean startsWith(String prefix)
如果之前已经插入的字符串word
的前缀之一为prefix
,返回true
;否则,返回false
。
示例:
输入 ["Trie", "insert", "search", "search", "startsWith", "insert", "search"] [[], ["apple"], ["apple"], ["app"], ["app"], ["app"], ["app"]] 输出 [null, null, true, false, true, null, true]解释 Trie trie = new Trie(); trie.insert("apple"); trie.search("apple"); // 返回 True trie.search("app"); // 返回 False trie.startsWith("app"); // 返回 True trie.insert("app"); trie.search("app"); // 返回 True
提示:
1 <= word.length, prefix.length <= 2000
word
和prefix
仅由小写英文字母组成insert
、search
和startsWith
调用次数 总计 不超过3 * 104
次
解题思路:最基础的线段树题目。长时间不刷题都快忘干净了,参考了官方题解,但因为使用了递归导致内存和运行时间偏高。 还有就是用Java写数据结构好别扭(奈何C++都快忘干净了)。
class Trie {private final Trie[] children ;private boolean isEnd = false;public Trie() {children = new Trie[26];}public void insert(String word) {if(word.length() == 0){isEnd = true;return;}char ch = word.charAt(0);int index = ch - 'a';if(children[index] == null){children[index] = new Trie();}children[index].insert(word.substring(1));}public boolean search(String word) {Trie trie = searchPrefix(word);return trie != null && trie.isEnd;}public boolean startsWith(String prefix) {return searchPrefix(prefix) != null;}public Trie searchPrefix(String prefix){if(prefix.length() == 0){return this;}int index = prefix.charAt(0) - 'a';return children[index] == null ? null : children[index].searchPrefix(prefix.substring(1));}
}