【Lintcode】1390. Short Encoding of Words

題目地址:

https://www.lintcode.com/problem/short-encoding-of-words/description

給定一個字符串列表,現在給出一個編碼方式,例如對於["time", "me", "bell"]來說,可以如下進行編碼:編碼由兩部分組成,一部分是字符串S = "time#bell#",另一部分是個數組[0, 2, 5],解碼的時候只需要從數組中取出一個數字作爲起始下標,然後從S的這個下標開始向後走到#即得到一個字符串。例如從下標爲0開始走到#得到的是time,下標爲2開始走到#得到的是me。這樣就可以還原出所有的字符串。很顯然編碼方式是不唯一的,並且有可能對應不同的字符串。要求求出所有編碼方式中可以得到的最短的S的長度是多少。

要得到最短的S只需要最大程度地複用字符串後綴即可。由此想到用Trie,每個字符串從後向前遍歷加入Trie中,這樣就複用了後綴,然後再用DFS求一下所有葉子節點的深度之和加11(加11是因爲#也佔一個位置)即可。代碼如下:

public class Solution {
    
    class Trie {
        class Node {
            Node[] nexts;
            Node() {
                nexts = new Node[26];
            }
        }
        
        Node root;
        
        public Trie() {
            root = new Node();
        }
        
        public void insert(String s) {
            Node cur = root;
            // 加單詞的時候要逆序遍歷加進去
            for (int i = s.length() - 1; i >= 0; i--) {
                char c = s.charAt(i);
                if (cur.nexts[c - 'a'] == null) {
                    cur.nexts[c - 'a'] = new Node();
                }
                cur = cur.nexts[c - 'a'];
            }
        }
        
        public int dfs() {
            return dfs(root, 0);
        }
        
        private int dfs(Node root, int depth) {
            int res = 0;
            boolean isLeaf = true;
            for (int i = 0; i < root.nexts.length; i++) {
                if (root.nexts[i] != null) {
                    isLeaf = false;
                    res += dfs(root.nexts[i], depth + 1);
                }
            }
            
            // 如果走到了葉子,則返回深度 + 1,否則累加所有分叉的(葉子深度 + 1)然後返回
            if (isLeaf) {
                return depth + 1;
            } else {
                return res;
            }
        }
    }
    
    /**
     * @param words:
     * @return: nothing
     */
    public int minimumLengthEncoding(String[] words) {
        Trie trie = new Trie();
        // 先將所有單詞加入trie
        for (String word : words) {
            trie.insert(word);
        }
        
        return trie.dfs();
    }
}

時空複雜度O(n)O(n)nn爲Trie的節點個數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章