1、按单词长度排序,索引后缀;拼接字符串计算长度
2、set清除重复字符串,作为后缀;然后对每个单词截取后面的部分进行判断set是否包含,包含则证明set该元素是该单词的词尾。最后计算长度(不过计算长度对set的处理有转为数组和直接遍历,直接遍历要更快一点,少了转数组的一层运算)
题目:
- 单词的压缩编码
给定一个单词列表,我们将这个列表编码成一个索引字符串 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
每个单词都是小写字母 。
解法:
// Solution One
/**
* @param {string[]} words
* @return {number}
*/
// 296ms 51.8mb
var minimumLengthEncoding0 = function(words) {
words.sort((a,b) => { return b.length > a.length})
// console.log(words)
let str = ""
for(let i = 0,len = words.length; i < len; i++){
if(str.indexOf((words[i] + "#")) === -1){
str += words[i] + "#"
}
}
console.log(str)
return str.length
};
// Solution Two
// set
var minimumLengthEncoding1 = function(words) {
let wordSet = new Set(words)
for(let w of wordSet){
for(let i = 1; i < w.length; i++){
// 查看词尾是否在set中
let t = w.slice(i)
wordSet.has(t) && wordSet.delete(t)
}
}
// 108ms 44.9mb
// return Array.from(wordSet).join('#').length + 1
// 96ms 43.1mb
let res = 0
wordSet.forEach(w => {
res += w.length+1
})
return res
}