words 的有效编码由任意助记字符串 s 和下标数组 indices 组成,且满足:
words.length == indices.length。s 以 "#" 字符结尾。indices[i],s 的一个从 indices[i] 开始、到下一个 "#" 字符结束(但不包括 "#")的子字符串恰好与 words[i] 相等。words,返回成功对 words 进行编码的最小助记字符串 s 的长度。words 排序,排序规则是单词长度越短排得越前。count,当 count 值为 0,说明该节点为前缀树的叶子节点。a 是单词 b 的后缀,则单词 a 在树中的结尾节点 count != 0】count 是否为 0,如果为 0,则计算进最后结果中。class Trie
{
public:
vector<Trie*> next;
string prefix;
Trie(): next(26) {}
};
class Solution
{
private:
Trie* root;
public:
int minimumLengthEncoding(vector<string>& words)
{
sort(words.begin(), words.end(), [&](const string& a, const string& b)
{
return a.size() < b.size();
});
for(auto& word : words)
reverse(word.begin(), word.end());
root = new Trie();
unordered_set<string> ss;
for(auto& word : words)
{
Trie* cur = root;
for(char& c : word)
{
if(!cur->next[c-'a']) cur->next[c-'a'] = new Trie();
cur = cur->next[c - 'a'];
if(cur->prefix.size() > 0) if(ss.count(cur->prefix)) ss.erase(cur->prefix);
}
cur->prefix = word;
ss.insert(word);
}
int ans = ss.size();
for(auto& word : ss) ans += word.size();
return ans;
}
};
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> nodes;
for (int i = 0; i < (int)words.size(); ++i) {
string word = words[i];
TrieNode* cur = trie;
for (int j = word.length() - 1; j >= 0; --j)
cur = cur->get(word[j]);
nodes[cur] = i;
}
int ans = 0;
for (auto& [node, idx] : nodes) {
if (node->count == 0) {
ans += words[idx].length() + 1;
}
}
return ans;
}
};