820. 单词的压缩编码


820. 单词的压缩编码

给定一个单词列表,我们将这个列表编码成一个索引字符串 S 与一个索引列表 A。

例如,如果这个列表是 [“time”, “me”, “bell”],我们就可以将其表示为 S = “time#bell#” 和 indexes = [0, 2, 5]。

对于每一个索引,我们可以通过从字符串 S 中索引的位置开始读取字符串,直到 “#” 结束,来恢复我们之前的单词列表。

那么成功对给定单词列表进行编码的最小字符串长度是多少呢?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/short-encoding-of-words
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

示例:

输入: words = ["time", "me", "bell"]
输出: 10
说明: S = "time#bell#" , indexes = [0, 2, 5] 。
提示:
1 <= words.length <= 2000
1 <= words[i].length <= 7
每个单词都是小写字母 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/short-encoding-of-words
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

方法一:暴力破解

class Solution {
public:
    int minimumLengthEncoding(vector<string>& words) {
        unordered_set<string> good(words.begin(), words.end());
        for(auto v:good){
            for(int i = 1;i<v.length();i++){
                string s = v.substr(i);
                cout<<s<<endl;
                good.erase(s);
            }
        }
        int sum = 0;
        for(auto v:good){
            sum+=(v.length()+1);
        }
        return sum;
    }
};

方法二,字典树

字典树,倒序插入,然后遍历树,判断最后一个节点的长度,每个叶子节点长度加一的和为答案.

int sum = 0;
int cnt = 0;
struct node{
    int data[27];
    void init(){
        for(int i = 0;i<26;i++){
            data[i]=-1;
        }
    }
}tree[140000+50];
void buildtree(string s){
    int p= 0;
    for(int i = s.length()-1 ; i>=0 ; i--){
        int x = s[i]-'a';
        if(tree[p].data[x]==-1){
            tree[p].data[x]=++cnt;
            tree[cnt].init();
        }
        p = tree[p].data[x];
    }
}
bool check(int n){ //判断是否是叶子节点
    for(int i = 0;i<26;i++){
        if(tree[n].data[i]!=-1){
            return false;
        }
    }
    return true;
}
void dfs(int n,int ans){
    if(check(n)){
        sum+=(ans+1);
        return ;
    }
    for(int i = 0;i<26;i++){
        if(tree[n].data[i]!=-1){
            dfs(tree[n].data[i],ans+1); //dfs遍历
        }
    }
}

class Solution {
public:
    int minimumLengthEncoding(vector<string>& words) {
        cnt = 0;
        sum = 0;
        tree[cnt].init();
        for(auto v:words){
            buildtree(v);
        }
        dfs(0,0);
        return sum;
    }
};

文章作者: anlen123
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 anlen123 !
 上一篇
55. 跳跃游戏 55. 跳跃游戏
55. 跳跃游戏难度中等643 给定一个非负整数数组,你最初位于数组的第一个位置。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个位置。 示例 1: 输入: [2,3,1,1,4] 输出: true 解释:
2020-05-07 anlen123
下一篇 
572. 另一个树的子树 572. 另一个树的子树
572. 另一个树的子树给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。 示例 1:给定的树 s: 3
2020-05-07 anlen123
  目录