题干
给定一个单词列表,我们将这个列表编码成一个索引字符串 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
每个单词都是小写字母 。
想法
这道题很难读懂题意,索引的意思是,从索引的位置开始一直读,指导碰到了#
然后只要返回最短长度
显然如果某个元素是另一个的一部分,那么就把不要它
那就想到字典书
这个讲的更好
直接看代码
package daily;
import java.util.Arrays;
public class MinimumLengthEncoding {
public int minimumLengthEncoding(String[] words) {
int len=0;
Tire tire=new Tire();
// 先对单词列表根据单词长度由长到短排序
Arrays.sort(words,(s1,s2) ->s2.length() -s1.length());
// 单词插入tire,返回该单词增加的编码长度
for (String word:words
) {
len+=tire.insert(word);
}
return len;
}
public static void main(String[] args){
MinimumLengthEncoding minimumLengthEncoding=new MinimumLengthEncoding();
String[] test={"time", "me", "bell"};
System.out.println(Arrays.toString(test));
System.out.println(minimumLengthEncoding.minimumLengthEncoding(test));
}
}
class TireNode{
char val;
TireNode[] children=new TireNode[26];
public TireNode(){
}
}
class Tire{
TireNode root;
public Tire() {
root = new TireNode();
}
//倒着插入,如果已经有了就不管
public int insert(String word){
TireNode tem= root;
boolean isNew=false;
for(int i=word.length()-1;i>=0;i--){
int c=word.charAt(i)-'a';
if(tem.children[c]==null){
isNew=true;
tem.children[c]=new TireNode();
}
tem=tem.children[c];
}
if(isNew){
return word.length()+1;
}
return 0;
}
}