Leetcode 820:單詞的壓縮編碼(超詳細的解法!!!)

給定一個單詞列表,我們將這個列表編碼成一個索引字符串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. 1 <= words.length <= 2000
  2. 1 <= words[i].length <= 7
  3. 每個單詞都是小寫字母 。

解題思路

這個問題是Leetcode 943:最短超級串簡化版,通過觀察可以發現,在這個問題中,如果一個字符串是另一個字符串的後綴,那麼可以將這兩個字符串進行合併,合併的同時記錄兩個字符串的起始位置,並且結束位置添加'#'。例如:

time
  me
-----
time#  起始位置:[0, 2]

我們希望最後得到的字符串長度最短,那麼就希望儘可能合併的字符串較長,這明顯就是Trie的性質了Leetcode 208:實現 Trie (前綴樹)(只需要將字符串反轉即可使用Trie)。最後統計Trie所有葉子節點深度+1(添加"#")的和就是我們的結果。

葉子節點的判斷有兩種思路:1)所有單詞插入結束後,dfs判定葉子節點。 2)每插入一個單詞,記錄最後字符(很可能就是葉子),然後遍歷所有記錄的葉子,如果其後沒有節點,那它確實就是葉子節點了。

class Node:
    def __init__(self):
        self.next = dict()
        
class Trie:
    def __init__(self):
        self.root = Node()
        self.nodes = dict()

    def insert(self, word, i):
        cur = self.root
        for c in word:
            if c not in cur.next:	# here
                cur.next[c] = Node()
            cur = cur.next[c]
            
        self.nodes[cur] = i

class Solution:
    def minimumLengthEncoding(self, words: List[str]) -> int:
        root = Trie()
        for i, word in enumerate(words):
            root.insert(word[::-1], i)

        res = 0
        for k, v in root.nodes.items():
            if k.next: continue # 後面還有節點,那麼就不是葉子
            res += len(words[v]) + 1
        return res

pythonic的寫法:

class Solution:
    def minimumLengthEncoding(self, words: List[str]) -> int:
        words = list(set(words)) 
        Trie = lambda: collections.defaultdict(Trie)
        trie = Trie()
		
        # trie[S[0]][S[1]][S[2]][...][S[S.length - 1]]
        nodes = [reduce(dict.__getitem__, word[::-1], trie)
                 for word in words]

        return sum(len(word) + 1
                   for i, word in enumerate(words)
                   if len(nodes[i]) == 0)

reference:

https://leetcode-cn.com/problems/short-encoding-of-words/solution/dan-ci-de-ya-suo-bian-ma-by-leetcode-solution/

我將該問題的其他語言版本添加到了我的GitHub Leetcode

如有問題,希望大家指出!!!

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