LeetCode 820.題目-中等

1.題目

原題鏈接
給定一個單詞列表,我們將這個列表編碼成一個索引字符串 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] 。

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/two-sum
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

2.解題

問題的本質是找出所有無法成爲別的單詞的後綴的單詞。

方法一:所有單詞放入集合,依次刪除每個單詞的後綴

相關知識:
set.discard()
思路:

  • 因爲在hash set中刪除操作效率高。而且放入集合可以去重。所以先講words數組放入set中
  • 對每個單詞。遍歷它的所有後綴。並從set中刪除
  • 注意使用set.discard()方法而不是remove()方法。後者若刪除元素不存在會報錯,而前者不會。
  • 複雜度分析:
    時間複雜度 O(wi2)O\left(\sum w_{i}^{2}\right), 其中wiw_i是 words[i] 的長度。每個單詞有wiw_i個後綴,對於每個後綴,查詢其是否在集合中時需要進行O(wi)O(w_i)的哈希值計算。
    空間複雜度 O(wi)O\left(\sum w_{i}\right), 存儲單詞的空間開銷
class Solution:
    def minimumLengthEncoding(self, words: List[str]) -> 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)

在這裏插入圖片描述

方法二:字典樹

相關知識:
能自動賦初始值的字典-collections.defaultdict()方法
python中的lambda關鍵字
字典樹Trie
python中的reduce()方法-序列迭代方法
python中的特殊方法__getitem__()方法
python中的enumerate()函數-返回枚舉對象
使用__getitem__魔法函數實現多層嵌套字典:博主自己實現了多層嵌套字典的__getitem__方法,並指出collections.defaultdict類中已經實現了類似的方法(這也就是我們下面用到的)

思路:

  • 利用數組的in方法和List的index方法
  • 遍歷數組的數nums[i],通過in方法**target-num[i]**判斷是否在數組內,如果在,則使用index方法獲得下標。(注意要判斷是否是使用了重複的元素)
class Solution:
    def minimumLengthEncoding(self, words: List[str]) -> int:
        words = list(set(words)) # 去掉重複。必須要去掉重複!
        Trie = lambda: collections.defaultdict(Trie) # lambda構造函數,嵌套字典
        trie = Trie()
        # getitem方法能使對應字典出現key,但value是空的{}
        # Trie是一個嵌套字典.
        # 對任一word[i]:S來說,reduce可以看成是一個循環,嵌套過程,
        # 完成reduce()操作能得到Trie[S[0]][S[1]][S[2]]...[S[len(S)-1]]的值,記爲L[i]
        # 對所有words進行這一操作, 就完成了嵌套字典的生成過程
        # 若word[i]不是別的單詞的後綴, 則L[i]必是空{},即len(L[i])==0
        # 若word[i]是別的單詞的後綴, 則L{i}必有值
        L = [reduce(dict.__getitem__, word[::-1], trie) for word in words]
        return sum(len(word)+1 for i, word in enumerate(words) if len(L[i]) == 0)

在這裏插入圖片描述

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