【LeetCode】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
  • 每个单词都是小写字母 。

思路一:存储后缀

将所有单词放在set中,对于对于set中每个单词,遍历其后缀,看是否在set中,如果在就删除,比如time,那么就遍历ime, me, e,删除me。这样就保证了set中留下来的单词不可能再合并了,最后遍历set加上每个单词长度和#号。

代码

时间复杂度:O($\sum w_{i}^2$),其中 $w_{i}$ 是words[i] 的长度,每个单词有 $w_{i}$ 个后缀,查询其是否在集合中需要进行O($w_{i}$)的哈希值计算。
空间复杂度:O($\sum w_{i}$),存储单词的空间开销。

class Solution {
public:
    int minimumLengthEncoding(vector<string>& words) {
        int res = 0;
        unordered_set<string> ust(words.begin(), words.end());
        for (string word : ust) {
            for (int i = 1; i < word.size(); ++i) {
                ust.erase(word.substr(i));
            }            
        }
        for (string word : ust) {
            res += word.size() + 1;
        }
        return res;
    }
};
posted @ 2020-03-28 22:53  Galaxy_hao  阅读(163)  评论(0编辑  收藏  举报