820.单词的压缩编码

题目地址:单词的压缩编码

主要思路就是:判断新的字符串是否是之前已有字符串的后缀,如果是,则不予考虑,进入下一循环,最后返回每个字符串长度加一的总和。

其中用到了集合Set,它的特点是不能包含重复元素;

String类的substring()方法有两种用法:

public String substring(int beginIndex)

或

public String substring(int beginIndex, int endIndex)
  • beginIndex -- 起始索引(包括),索引从 0 开始。

  • endIndex -- 结束索引(不包括)。

class Solution {
    public int minimumLengthEncoding(String[] words) {
        //先将每个字符串存储到集合HashSet中
        Set<String> chs = new HashSet<>(Arrays.asList(words));
        //对于每个字符串,如果它的后缀作为单独字符串出现在集合中,则将那个后缀的字符串删除
        for (String word : words) {
            for (int i = 1; i < word.length(); i++) {
                chs.remove(word.substring(i));
            }
        }
        int res = 0;
        //结果是每个字符串的长度加一的总和
        for (String word : chs) {
            res += word.length() + 1;
        }
        return res;
    }
}

结果:

另外一种方法:字典树,看了好一会儿,主要思想是将每个字符串反序插入一颗树中,给每个字符串的单个单词赋予一个计数器,如果为0则代表是叶子节点,代表没有后缀的单词,最后计算所有叶子节点的单词长度加一的和。

class Solution {
    public int minimumLengthEncoding(String[] words) {
        TrieNode trieNode = new TrieNode();
        Map<TrieNode,Integer> chs = new HashMap();
        //遍历每个字符串
        for (int i = 0; i < words.length; i++) {
            String word = words[i];
            TrieNode cur = trieNode;
            /*如果当前字符串的该字符存在,则直接返回,
            若不存在,则创建一个节点,且该字符的计数器加一,表明其已不是叶子节点*/
            for (int j = word.length()-1; j >= 0 ; --j) {
                cur = cur.get(word.charAt(j));
            }
            //将该单词存入集合,单词为键,下标为值
            chs.put(cur,i);
        }
        int res = 0;
        for (TrieNode node : chs.keySet()) {
            //如果为叶子节点,找到该单词下标,求单词长度加一
            if (node.count == 0)
                res += words[chs.get(node)].length() + 1;
        }
        return res;
    }
    class TrieNode{
        TrieNode[] child;
        int count;
        //构造函数,计数器初始为0
        TrieNode(){
            child = new TrieNode[26];
            count = 0;
        }
        public TrieNode get(char c){
            if (child[c-'a'] == null){
                child[c-'a'] = new TrieNode();
                count ++;
            }
            return child[c-'a'];
        }
    }
}

结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值