LeetCode 820. 单词的压缩编码 (Java版; Meidum)

welcome to my blog

LeetCode 820. 单词的压缩编码 (Java版; Meidum)

题目描述

给定一个单词列表,我们将这个列表编码成一个索引字符串 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
每个单词都是小写字母 。

第一次做; 核心: 1)前缀树; 使用哈希表记录邻居, 方便知道当前节点是否有邻居, 通过isEmpty()判断; 使用数组记录邻居就不方便判断是否有邻居了

class Solution {
    public int minimumLengthEncoding(String[] words) {
        HashSet<String> set = new HashSet<>(Arrays.asList(words));
        Trie trie = new Trie();
        for(String s : set){
            trie.add(s);
        }
        return trie.getDepthSum();
    }
    class Trie{
        Node root;
        HashSet<Node> set;
        Trie(){
            root = new Node();
            //装叶子节点; 但是有些叶子节点可能之后就不是叶子节点了, 要小心
            set = new HashSet<>();
        }

        void add(String str){
            Node cur = root;
            for(int i=str.length()-1; i>=0; i--){
                char ch = str.charAt(i);
                // int index = ch - 'a';
                if(!cur.next.containsKey(ch)){
                    cur.next.put(ch, new Node());
                }
                cur = cur.next.get(ch);
            }
            cur.depth = str.length()+1;//算上#占用的一个深度
            set.add(cur);
        }

        int getDepthSum(){
            int res = 0;
            for(Node node : set){
                if(node.next.isEmpty()){
                    res += node.depth;
                }
            }
            return res;
        }
    }

    class Node{
        // Node[] nexts;
        HashMap<Character, Node> next;
        int depth;
        Node(){
            // nexts = new Node[26];
            next = new HashMap<>(); //用哈希表的好处是方便直到当前字符有没有下一个字符, 根据isEmpty()判断, 用数组的话就不行了
        }
    }
}

第一次做; 核心: 1)使用set记录每个单词, 然后针对每一个单词, 考虑其子串[i,n-1], 将该子串从set中删除, i>=1, 因为这些子串都是当前单词的后缀 2) HashSet可以使用forEach, HashMap不行 3)Arrays.asList(T… a), 返回值类型是List 3)将所有单词放入set, 可以先过滤掉重复出现的单词

class Solution {
    public int minimumLengthEncoding(String[] words) {
        Set<String> set = new HashSet(Arrays.asList(words));
        for(String word : words){
            for(int i=1; i<word.length(); i++){
                set.remove(word.substring(i));
            }
        }
        int res=0;
        for(String s : set){
            res += s.length()+1;
        }
        return res;
    }
}

LeetCode优秀题解 JDK8新特性, stream()

 public int minimumLengthEncoding(String[] words) {
        Node trie = new Node();
        Set<Node> nodes = new HashSet<>();
        for (String w : words) {
            Node node = trie;
            for (int i = w.length() - 1; i >= 0; i--)
                node = node.add(w.charAt(i));
            node.depth = w.length() + 1;
            nodes.add(node);
        }
        return nodes.stream().filter(n -> n.leaf).mapToInt(n -> n.depth).sum();
    }

    class Node {
        final Node[] next = new Node[26];
        boolean leaf = true;
        int depth;

        Node add(char c) {
            if (next[c - 'a'] == null)
                next[c - 'a'] = new Node();
            leaf = false;
            return next[c - 'a'];
        }
    }
class Solution {
    public int minimumLengthEncoding(String[] words) {
        TrieNode root = new TrieNode();
        List<TrieNode> leaves = new  ArrayList<TrieNode>();
        for (String w : new HashSet<>(Arrays.asList(words))) {
            TrieNode cur = root;
            for (int i = w.length() - 1; i >= 0; --i) {
                char j = w.charAt(i);
                if (!cur.next.containsKey(j)) cur.next.put(j, new TrieNode());
                cur = cur.next.get(j);
            }
            cur.depth = w.length() + 1;
            leaves.add(cur);
        }
        int res = 0;
        for (TrieNode leaf : leaves) if (leaf.next.isEmpty()) res += leaf.depth;
        return res;
    }
}

class TrieNode {
    HashMap<Character, TrieNode> next = new HashMap<>();
    int depth;
}

你可能感兴趣的:(AlibabaLeetCode,字符串,leetcode,java)