# 820. Short Encoding of Words

**<font color=red>难度: Medium</font>**

## 刷题内容

> 原题连接

* https://leetcode.com/problems/short-encoding-of-words/

> 内容描述

```
Given a list of words, we may encode it by writing a reference string S and a list of indexes A.

For example, if the list of words is ["time", "me", "bell"], we can write it as S = "time#bell#" and indexes = [0, 2, 5].

Then for each index, we will recover the word by reading from the reference string from that index until we reach a "#" character.

What is the length of the shortest reference string S possible that encodes the given words?

Example:

Input: words = ["time", "me", "bell"]
Output: 10
Explanation: S = "time#bell#" and indexes = [0, 2, 5].
 

Note:

1 <= words.length <= 2000.
1 <= words[i].length <= 7.
Each word has only lowercase letters.
```

## 解题方案

> 思路 1
******- 时间复杂度: O(sum(len(word)^2 for word in words))******- 空间复杂度: O(sum(len(word) for word in words))******

因为我们最后可以从index恢复我们的words，即从某个index开始走，直到碰到'#'了就走完了一个word，
那么说明我们可以remove掉的word一定是某一个其他word的suffix

beats 76.42%

```python
class Solution:
    def minimumLengthEncoding(self, words):
        """
        :type words: List[str]
        :rtype: int
        """
        good = set(words)
        for word in words:
            for k in range(1, len(word)):
                good.discard(word[k:])

        return sum(len(word) + 1 for word in good)
```


> 思路 2
******- 时间复杂度: O(sum(len(word) for word in words))******- 空间复杂度: O(sum(len(word) for word in words))******

Trie树，我们将word倒着挂在trie树上，那么是suffix的word就不可能是叶子节点了

直接抄的[solution](https://leetcode.com/problems/short-encoding-of-words/solution/)


```python
from functools import reduce
class Solution:
    def minimumLengthEncoding(self, words):
        """
        :type words: List[str]
        :rtype: int
        """
        words = list(set(words)) #remove duplicates
        #Trie is a nested dictionary with nodes created
        # when fetched entries are missing
        Trie = lambda: collections.defaultdict(Trie)
        trie = Trie()

        #reduce(..., S, trie) is trie[S[0]][S[1]][S[2]][...][S[S.length - 1]]        
        nodes = [reduce(dict.__getitem__, word[::-1], trie)
                 for word in words]

        # node[i] 就是该word reduce到最后的空trie，即{}，说明该word reduce到最后是叶子节点
        return sum(len(word) + 1
                   for i, word in enumerate(words)
                   if len(nodes[i]) == 0) 
```























