208. 实现 Trie (前缀树)
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 * 10^4
次
方法一:字典树
解题思路
- 这东西就是个 字典树,字典树解释参考百度百科。
- 小写字母最多 26 个,可以用数组实现 children。
- 方便编码,抽象出节点类
TrieNode
,具体实现看代码。
参考代码
class Trie {
/** 节点类 */
class TrieNode {
// 子节点,最多 26 个
private final TrieNode[] children;
// 是否是单词结尾
private boolean isEnd;
public TrieNode() {
children = new TrieNode[26];
}
}
private final TrieNode root;
/** Initialize your data structure here. */
public Trie() {
root = new TrieNode();
}
/** Inserts a word into the trie. */
public void insert(String word) {
TrieNode curr = root;
for (int i = 0; i < word.length(); i++) {
char ch = word.charAt(i);
if (curr.children[ch - 'a'] == null) {
curr.children[ch - 'a'] = new TrieNode();
}
curr = curr.children[ch - 'a'];
}
curr.isEnd = true;
}
/** Returns if the word is in the trie. */
public boolean search(String word) {
TrieNode curr = root;
for (int i = 0; i < word.length(); i++) {
char ch = word.charAt(i);
if (curr.children[ch - 'a'] == null) {
return false;
}
curr = curr.children[ch - 'a'];
}
return curr.isEnd;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
public boolean startsWith(String prefix) {
TrieNode curr = root;
for (int i = 0; i < prefix.length(); i++) {
char ch = prefix.charAt(i);
if (curr.children[ch - 'a'] == null) {
return false;
}
curr = curr.children[ch - 'a'];
}
return true;
}
}