Leetcode--Java--820. 单词的压缩编码

题目描述

在这里插入图片描述

样例描述

在这里插入图片描述

思路

方法一:存储后缀 + 哈希去重
如果一个单词不是任何其他单词的后缀,那么它就是最短的编码。反之,是的话可以删除。

  1. 首先全部加入Set集合去重,对于每个单词,结合数据范围,依次在set里面删除它们所有的后缀。剩余的就是可编码的单词。加上1(#字符)的长度就是答案
    方法二:排序 + 字典树
  2. 在方法一的基础上,可以把所有单词逆序挂在trie树上(方便查找后缀),在不断插入到树中,如果是新的单词,就需要编码为长度加一,否则直接用树上的不需要编码
  3. 注意要让长的单词先插入,如果短的先插入,并且是某长的后缀,将会被视为不同的。例如time,和me。 所以要先降序排序

代码

class Solution {
    public int minimumLengthEncoding(String[] words) {
        Set<String> set = new HashSet<>(Arrays.asList(words));
        //枚举删除每个单词的所有后缀
        for (String word: words) {
            //由数据范围比较小,直接枚举删除
            for (int k = 1; k < word.length(); k ++ ) {
                set.remove(word.substring(k, word.length()));
            }
        }
        //剩余的单词不是任何其他单词的后缀,  因此加上1 (#字符)求和就是答案
        int ans = 0;
        for (String s: set) {
            ans += s.length() + 1;
        }
        return ans;
    }
}

trie树

class Solution {
    
    class TrieNode {
        TrieNode tns[];
        boolean isWord;
        public TrieNode() {
            tns = new TrieNode[26];
        }
    }
    private TrieNode root;

    public int insert(String word) {
        TrieNode p = root;
        //是否是新的,原trie树中不存在
        boolean isNew = false;
        for (int i = word.length() - 1; i >= 0; i -- ) {
            int u = word.charAt(i) - 'a';
            if (p.tns[u] == null) {
                isNew = true;
                p.tns[u] = new TrieNode();
            }
            p = p.tns[u];
        }
        //是新的话,就返回长度加一(#的字符),否则不用编码
        return isNew ? word.length() + 1 : 0;
    }

    public int minimumLengthEncoding(String[] words) {
        root = new TrieNode();
       //降序排序
       Arrays.sort(words, (a, b) ->{
           return b.length() - a.length();
       });
        int ans = 0;
        for (String s: words) {
            ans += insert(s);
        }
        return ans;
                
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值