用C++实现字典树数据结构的例子:
例题:
- 单词的压缩编码
给定一个单词列表,我们将这个列表编码成一个索引字符串
S
与一个索引列表A
。
例如,如果这个列表是 ["time", "me", "bell"]
,我们就可以将其表示为 S = "time#bell#"
和 indexes = [0, 2, 5]
。
对于每一个索引,我们可以通过从字符串 S
中索引的位置开始读取字符串,直到 "#"
结束,来恢复我们之前的单词列表。
那么成功对给定单词列表进行编码的最小字符串长度是多少呢?
示例:
输入: words = ["time", "me", "bell"]
输出: 10
说明: S = "time#bell#" , indexes = [0, 2, 5] 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/short-encoding-of-words
本题是一个典型的字典树问题。这里对力扣官方给出的题解代码给出注释与解读(实现细节有改动)。关于字典树的原理,也可参见该链接:
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/short-encoding-of-words/solution/dan-ci-de-ya-suo-bian-ma-by-leetcode-solution/
class TrieNode{ //字典树数据结构建立
TrieNode* children[26];
public:
int count; //标记本节点拥有的孩子节点数
TrieNode(){//初始化
for(int i = 0; i < 26; i++){
children[i] = NULL;
}
count = 0;
}
TrieNode* get(char c){//查找一个孩子节点:若有则返回该节点,否则创造该孩子节点
if(children[c - ‘a‘] == NULL){
children[c - ‘a‘] = new TrieNode();
count++;
}
return children[c - ‘a‘];
}
};
class Solution {
public:
int minimumLengthEncoding(vector<string>& words) {
TrieNode* trie = new TrieNode();
unordered_map<TrieNode*, int> mp; //建立字典树节点到单词数组的映射
for(int i = 0; i < (int)words.size(); i++){
string word = words[i]; //选取一个单词
TrieNode* cur = trie;
for(int j = (int)word.size() - 1; j >= 0; j--){//逆序地加入单词中的字符,构成前缀树
cur = cur->get(word[j]);
} //将该单词中所有的字符依次检索或者插入到字典树内
mp[cur] = i; //标记字典树中节点对应的单词
}
int ans = 0;
for(auto& m: mp){
if(m.first->count == 0){//若哈希表中某节点没有孩子,那么意味着这个节点是单词的首字母
ans += (int)words[m.second].length() + 1;//构造压缩编码
}
}
return ans;
}
};
原文地址:https://www.cnblogs.com/moonwalker-hank/p/12653100.html
时间: 2024-10-07 15:11:33