首先明确解体思路,其实就是去除所有是后缀的单词,剩下的单词长度全部累加,再加上单词个数就是结果长度
存储后缀:
将所有字符串全部存入哈希 set 中,然后遍历所有字符的后缀,再去哈希 set 中查找是否有匹配的单词,如果匹配则删除
class Solution {
public:
int minimumLengthEncoding(vector<string>& words) {
std::unordered_set<std::string> s(words.begin(), words.end());
for (auto word : words) {
for (int i = 1; i < word.size(); ++i) {
s.erase(word.substr(i));
}
}
int len = 0;
for (auto word : s) {
len += word.size() + 1;
}
return len;
}
};
字典树:
将所有字符倒叙之后变成字典树,这样这棵树就是结果集,将树的所有结点和字符串的索引通过map绑定,
叶子结点的索引所对应的字符串就是结果集,并且叶子结点的 count 为 0
class Solution {
struct TrieNode {
int count = 0;
vector<TrieNode*> child = vector<TrieNode*>(26, nullptr);
TrieNode* get(char c) {
if (nullptr == child[c - 'a']) {
child[c - 'a'] = new TrieNode();
++count;
}
return child[c - 'a'];
}
};
public:
int minimumLengthEncoding(vector<string>& words) {
unordered_map<TrieNode*, int> nodes;
TrieNode* trie = new TrieNode();
for (int i = 0; i < words.size(); ++i) {
TrieNode* cur = trie;
for (auto it = words[i].rbegin(); it != words[i].rend(); ++it) {
cur = cur->get(*it);
}
nodes[cur] = i;
}
int ans = 0;
for (auto [node, index] : nodes) { // C++ 17 标准才能识别
if (node->count == 0) {
ans += words[index].size() + 1;
}
}
return ans;
}
};