208. 实现 Trie (前缀树) 【中等题】
实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作。
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
题目讲解
【解题要点】
- 设计合适的数据结构
【讲解】
假如我们的词有apple,apply,bed,bear,beat,beach
那我们应该构建如下的前缀树:
那么如何用合适的数据结构来实现这颗前缀树呢?我们用这样的数据结构 :
class TriNode{
TriNode[] children = new TriNode[26];
boolean isEnd = false;
}
下面我们以bed,bear
为例来讲解一下前缀树的实现(为了画图方便,我们假设字母表只有5个字母):
- 开辟5个单位的空间
- 遍历第一个单词
bed
,将b
加入空间中,同时为b
开辟了5个空间 - 将
e
加入空间中,同时为e
开辟了5个空间 - 将
d
加入空间中,同时为d
开辟了5个空间 - 至此,
bed
构建完毕。构建流程如下图
6. 遍历第二个单词bear
,因为b,e
的位置都已经存在元素了,所以接着在e
开辟的空间中,为a
开辟5个空间。最后将r
加入空间中,同时为r
开辟5个空间
7. 最后将上述流程翻译成代码
【代码】
class TriNode{
TriNode[] children = new TriNode[26];
boolean isEnd = false;
}
public class Trie {
TriNode root;
/** Initialize your data structure here. */
public Trie() {
root = new TriNode();
}
/** Inserts a word into the trie. */
public void insert(String word) {
TriNode node = root;
for (char c: word.toCharArray()){
if (node.children[c-'a'] == null){
node.children[c-'a'] = new TriNode();
}
node = node.children[c-'a'];
}
node.isEnd = true;
}
/** Returns if the word is in the trie. */
public boolean search(String word) {
TriNode node = root;
for (char c: word.toCharArray()){
if (node.children[c-'a'] == null)
return false;
node = node.children[c-'a'];
}
return node.isEnd;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
public boolean startsWith(String prefix) {
TriNode node = root;
for (char c: prefix.toCharArray()){
if (node.children[c-'a'] == null)
return false;
node = node.children[c-'a'];
}
return true;
}
}
关注微信公众号“算法岗从零到无穷”,更多算法知识点告诉你。