链接:208. 实现 Trie (前缀树) - 力扣(LeetCode)
Tire(发音类:似 "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
次
题意
很明显,题目要我们实现一个trie树的查找数据结构
思路
直接数据模拟trie树数据结构,定义cnt数组来记录哪个位置出现过一个完整的单词,查找前缀的话,只要出现过的直接返回true,否则直接返回false,插入的话直接插入,模拟下一个层即可
代码
cpp
class Trie {
public:
int idx = 0;
int cnt[300010]={0}; //定义cnt来记录当前位置是一个完整的单词
int trie[300010][30]; //定义trie数组,最多调用3*10*4个数据,说明可能最大层为这么大,然后的30是定义的26个字母 0-25
Trie() {
}
void insert(string word) {
int p = 0;
for(auto c:word){
int val = c-'a'; //转变为0-25
if(!trie[p][val]) trie[p][val]=++idx; //在当前层数未出现
p = trie[p][val]; //转为下一层
}
//cout<<"insert::" <<p<<endl;
cnt[p]++; //记录当前层的位置为一个完整单词
}
bool search(string word) {
int p = 0;
for(auto c:word){
int val = c-'a';
if(!trie[p][val]) return false; //找不到下一个位置的字母,直接返回false
p = trie[p][val];
}
//cout<<word<<" "<<"search::"<<p<<endl;
return cnt[p]; //判断当前位置是否是一个完整单词
}
bool startsWith(string prefix) {
int p = 0;
for(auto c:prefix){
int val = c-'a';
if(!trie[p][val]) return false;
p = trie[p][val];
}
//没有查不到,说明是某个单词的前缀
return true;
}
};
/**
* Your Trie object will be instantiated and called as such:
* Trie* obj = new Trie();
* obj->insert(word);
* bool param_2 = obj->search(word);
* bool param_3 = obj->startsWith(prefix);
*/