给定一个单词列表,我们将这个列表编码成一个索引字符串 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
每个单词都是小写字母 。
通过次数42,676提交次数86,075
思路:
这里明显是要用字典树。但是用法是讲单词reverse后加入字典树。同时树要记录结点深度。
构成字典树后,用dfs递归遍历树,遍历到叶子结点时,把叶子结点深度+1的值加入到res当中。
class Solution {
class Node{
char val;
Node[] next;
boolean isWord;
int count;
Node(char c){
this.val = c;
this.next = new Node[26];
this.count = 0;
}
}
Node root = new Node('(');
public void insert(String word){
Node cur = root;
int count = 0;
for(char c:word.toCharArray()){
int index = c - 'a';
if(cur.next[index]==null){
cur.next[index] = new Node(c);
}
count ++;
cur = cur.next[index];
}
cur.isWord = true;
cur.count = count;
}
int res;
public int minimumLengthEncoding(String[] words) {
for(int i=0;i<words.length;i++){
String reverse = new StringBuffer(words[i]).reverse().toString();
insert(reverse);
}
dfs(root);
return res;
}
//dfs遍历所有的结点,把叶子结点的count+1 +到res中.
public void dfs(Node cur){
boolean flag = true;
for(int i=0;i<26;i++){
if(cur.next[i]!=null){
flag = false;
break;
}
}
if(flag){
res += cur.count+1;
return;
}
for(int i=0;i<26;i++){
if(cur.next[i]!=null){
dfs(cur.next[i]);
}
}
}
}