字典树解法
//字典树的结点
class TireNode{
public char val;
//一个字母结点的后代可能有26个(a - z)
public TireNode[] children = new TireNode[26];
public TireNode() {
val = ' ';
}
public TireNode(char val) {
this.val = val;
}
}
//字典树
class Tire{
//头结点,自身不存储任何信息,子结点才存储信息
private TireNode root;
public Tire() {
root = new TireNode();
}
public Tire(TireNode root) {
this.root = root;
}
//插入新单词
public int insert(String word){
TireNode cur = root;
boolean isNew = false;
//单词从尾部开始遍历,且当前的单词长度小于所有已经插入的单词的长度
for(int i = word.length() - 1; i >= 0; i--){
char c = word.charAt(i);
/*
由于当前单词的长度小于所有已经插入的单词的长度,
当出现新的字母的时候,该单词就无法利用已有的字典树,
例如:user和loser(倒序为"resu" 和 "resol")
的编码长度应为11("user#loser#")。
*/
if(cur.children[c - 'a'] == null){
cur.children[c - 'a'] = new TireNode(c);
cur = cur.children[c - 'a'];
isNew = true;
}
else {
cur = cur.children[c - 'a'];
}
}
return isNew? word.length() + 1 : 0;
}
}
class Solution {
public int minimumLengthEncoding(String[] words) {
Tire tire = new Tire();
int len = 0;
//将单词按长度降序排列
Arrays.sort(words, (s, t) -> {return -(s.length() - t.length());});
//往字典树插入单词
for(String s : words){
len += tire.insert(s);
}
return len;
}
}