820. 单词的压缩编码

题目:

给定一个单词列表,我们将这个列表编码成一个索引字符串 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] 。
 

提示:

1 <= words.length <= 2000
1 <= words[i].length <= 7
每个单词都是小写字母 。

解答:

开始暴力法做的,但19个用例就过不去了,查也查不出来。

正确做法1:

对于一个字符串"abcdef"。如果存在另一个字符串"ef",那么ef就可以直接忽略。因为abcdef在最终字符串中是这样的:xxxx abcdef# xxxx。按照题意,ef直接可以索引到,也不用再加其他'#'号。

也就是说任意字符串,如果其后缀也出现在数组里,就可以忽略掉该后缀。

按照上面的法则对数组进行筛选,剩下的就是最终的S串,注意每个字符串要加一个'#'号。

class Solution {
public:
    int minimumLengthEncoding(vector<string>& words) {
        unordered_set<string> st(words.begin(),words.end());
        for(const string& s:words){
            for(int i=1;i<s.size();++i){//i=1开始!!!不能把自己删了!
                st.erase(s.substr(i));
            }
        }
        int res=0;
        for(const auto& s:st){
            res+=s.size()+1;
        }
        return res;
    }
};

 

 

第二个前缀树方法,有点难想:

首先是要反向思维,把单词倒序放入字典树(因为是求后缀相同的单词)。还要先对words进行排序,先把长单词放入字典树,再考虑短单词。如果不排序,后面会非常复杂,因为不知道当前单词该不该加'#'。

class trie{
    public:
    char c;
    vector<trie*> next;
    trie():c('0') {
        next.resize(26);
    }
    trie(char x):c(x){
        next.resize(26);
    }
};


class Solution {
public:
    int minimumLengthEncoding(vector<string>& words) {
        sort(words.begin(),words.end(),[](const string& a,const string& b){return a.size()>b.size();});
        trie root;
        int res=0;
        for(const auto& s:words){
            string tmp=s;
            reverse(tmp.begin(),tmp.end());//倒着插入字典树,因为要比较后缀,转化为比较前缀,巧妙的思路阿!
            trie* cur_trie=&root;
            bool flag=false;
            for(int i=0;i<tmp.size();++i){
                if(cur_trie->next[tmp[i]-'a']==nullptr){
                    cur_trie->next[tmp[i]-'a']=new trie(tmp[i]);
                    flag=true;
                    cur_trie=cur_trie->next[tmp[i]-'a'];
                }
                else{
                    cur_trie=cur_trie->next[tmp[i]-'a'];
                }
            }
            res+=flag?s.size()+1:0;
        }
        return res;
    }
};

 

posted @ 2020-03-28 21:04  NeoZy  阅读(179)  评论(0编辑  收藏  举报