难度: 中等
题目:
Trie(发音类似 “try”)或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。
请你实现 Trie 类:
输入
[“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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/implement-trie-prefix-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
Trie树,又称前缀树、字典树、单词查找树。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。
该题就是实现字典树的操作。从根节点出发,每个节点定义26个分支,初始时为NULL。每个节点存储一个英文字母,一个单词从根节点出发往后存储。根节点不包含字符,除根节点外每一个节点都只包含一个字符; 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串; 每个节点的所有子节点包含的字符都不相同。同时,每个结点都需要一个bool类型参数用来判断当前位置是否是存储一个单词。
typedef struct Tree
{
struct Tree* data[26];
bool isWord;
}Tree;
class Trie {
private:
Tree *root;
public:
/** Initialize your data structure here. */
Trie() {
root = (Tree*)calloc(1, sizeof(Tree));
}
/** Inserts a word into the trie. */
void insert(string word) {
int n = word.size();
Tree *t = root;
for(int i = 0; i < n; i++)
{
if(t->data[word[i] - 'a'] == NULL)
t->data[word[i] - 'a'] = (Tree*)calloc(1, sizeof(Tree));
t = t->data[word[i] - 'a'];
}
t->isWord = true;
}
/** Returns if the word is in the trie. */
bool search(string word) {
Tree *t = root;
for(int i = 0; i < word.size(); i++)
{
if(t->data[word[i] - 'a'] == NULL)
return false;
t = t->data[word[i] - 'a'];
}
if(t->isWord)
return true;
else
return false;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
bool startsWith(string prefix) {
Tree *t = root;
for(int i = 0; i < prefix.size(); i++)
{
if(t->data[prefix[i] - 'a'] == NULL)
return false;
t = t->data[prefix[i] - 'a'];
}
return true;
}
};
学习了字典树的操作。解决该题使用了数组存储数据,实际还可用哈希表等降低空间复杂度。