給定一個單詞列表,我們將這個列表編碼成一個索引字符串 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] 。
鏈接:🔗
本題主要的難點: 怎麼判斷一個字符串是另外一個字符串的後綴
做法: 字典樹可以方便地解決判斷一個字符串是不是另外一個字符串地前綴問題,而後綴問題只需將待判斷地字符串翻轉(reverse)就再次轉變爲了前綴問題
class Solution {
public:
int trie[2010 * 7][30];
int len = 0,idx = 0;
void insert(string x){
int p = 0;
for (int i = 0; i < x.size(); ++i){
if (trie[p][x[i] - 'a'] == 0) trie[p][x[i] - 'a'] = ++idx;
p = trie[p][x[i] - 'a'];
}
}
void query(string x){
int p = 0;
for (int i = 0; i < x.size(); ++i){
if (trie[p][x[i] - 'a']) {
p = trie[p][x[i] - 'a'];
}
}
for (int i = 0; i <= 26; ++i)
if (trie[p][i] != 0) return;
len = len + x.size() + 1;
}
int minimumLengthEncoding(vector<string>& words) {
set<string> s;
for (auto x : words){
reverse(x.begin(),x.end());
insert(x);
}
for (auto x:words){
if (s.count(x) == 0){
s.insert(x);
reverse(x.begin(),x.end());
query(x);
}
}
return len;
}
};