2020.3.29
力扣周末回顾
非常重要的一道题
第一次碰见字典树
原题:点击此处
题目:对存在相同后缀的单词进行压缩。
(以后看到前缀,后缀的题目,优先想到字典树)
题解:
1.创建一棵字典树。根节点值域为空,其余节点的值域为26个字母中的一个,孩子节点是一个大小为26的节点数组,其余的节点同理。
2.遍历所有单词,从单词的最后一个字母往第一个字母遍历,目的是为了得到检测后缀。(此处需要把单词先从长到短进行排序)
原因:
“time”,“me”能找到me重复了。
但是“me”,"time"这样就找不到重复了。
3.只要发现有不重复的后缀,就把单词的长度+1加到答案总数上。
4.以后多练。
class Solution {
public int minimumLengthEncoding(String[] words) {
int length = words.length;
int ans = 0;
Trie trie = new Trie();
// 字符串从长到短排序
Arrays.sort(words,(s1,s2) -> s2.length() - s1.length());
for(int i = 0;i<length;i++){
ans += trie.Insert(words[i]);
}
return ans;
}
}
class Trie{
TrieNode root;
public Trie(){
root = new TrieNode();
}
// 字典树的插入
public int Insert(String str){
TrieNode cur = root;
char[] carry = str.toCharArray();
boolean flag = false;
// 倒序插入字典
for(int i = str.length()-1; i>=0 ;i--){
char c = carry[i];
// 代表还不存在这个字母
if(cur.children[c-'a'] == null){
flag = true;
cur.children[c-'a'] = new TrieNode(c);
}
// 指针交换
cur = cur.children[c-'a'];
}
if(flag){
return str.length()+1;
}
return 0;
}
}
// 字典树节点
class TrieNode{
char val;
// 26个字母的孩子节点
TrieNode[] children = new TrieNode[26];
public TrieNode(){}
public TrieNode(char c){
val = c;
}
}