Problem
Given a list of words, we may encode it by writing a reference string S and a list of indexes A.
For example, if the list of words is [“time”, “me”, “bell”], we can write it as S = “time#bell#” and indexes = [0, 2, 5].
Then for each index, we will recover the word by reading from the reference string from that index until we reach a “#” character.
What is the length of the shortest reference string S possible that encodes the given words?
Note:
- 1 <= words.length <= 2000.
- 1 <= words[i].length <= 7.
- Each word has only lowercase letters.
Example
Input: words = [“time”, “me”, “bell”]
Output: 10
Explanation: S = “time#bell#” and indexes = [0, 2, 5].
Solution
如果一个单词是另一个单词的后缀,那么它就不用被加入到压缩后的字符串当中。
本题可以使用字典树(Trie)解决,字典树中存储的是倒序的字符串。将输入字符串数组中的每个字符串插入字典树之前,需要先将输入数组按照字符串长度从长倒短进行排序。
注意调用STL的sort对字符串数组按长度排序的方法。
class Solution {
public:
class TrieNode
{
//char val;
//TrieNode* children[26];
public:
TrieNode* children[26];
TrieNode()
{
for(int i = 0;i<26;++i)
{
children[i] = NULL;
}
}
};
// 定义tire
class Trie
{
TrieNode* root;
public:
Trie()
{
root = new TrieNode();
}
int insert(string &word)
{
TrieNode *cur = root;
bool isNew = false;
// 倒着插入单词
for (int i = word.length() - 1; i >= 0; i--)
{
int c = word[i] - 'a';
if (cur->children[c] == NULL)
{
isNew = true; // 是新单词
cur->children[c] = new TrieNode();
}
cur = cur->children[c];
}
// 如果是新单词的话编码长度增加新单词的长度+1,否则不变。
return isNew? word.length() + 1: 0;
}
};
static bool myfunction (string &i,string &j)
{
return i.length()>j.length();
}
int minimumLengthEncoding(vector<string>& words) {
int len = 0;
Trie *trie = new Trie();
sort(words.begin(),words.end(),myfunction);
for (auto &word: words) {
len += trie->insert(word);
}
return len;
}
};