【哈希表】LeetCode 49. 字母異位詞分組【中等】

給你一個字符串數組,請你將 字母異位詞 組合在一起。可以按任意順序返回結果列表。

字母異位詞 是由重新排列源單詞的字母得到的一個新單詞,所有源單詞中的字母通常恰好只用一次。

示例 1:

輸入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
輸出: [["bat"],["nat","tan"],["ate","eat","tea"]]


示例 2:

輸入: strs = [""]
輸出: [[""]]


示例 3:

輸入: strs = ["a"]
輸出: [["a"]]
 

提示:

1 <= strs.length <= 104
0 <= strs[i].length <= 100
strs[i] 僅包含小寫字母

 

【分析】

兩個字符串互爲字母異位詞,當且僅當兩個字符串包含的字母相同。同一組字母異位詞中的字符串具備相同點,可以使用相同點作爲一組字母異位詞的標誌,使用哈希表存儲每一組字母異位詞,哈希表的鍵爲一組字母異位詞的標誌,哈希表的值爲一組字母異位詞列表。

遍歷每個字符串,對於每個字符串,得到該字符串所在的一組字母異位詞的標誌,將當前字符串加入該組字母異位詞的列表中。遍歷全部字符串之後,哈希表中的每個鍵值對即爲一組字母異位詞。

以下兩種方法分別使用排序和計數作爲哈希表的鍵。

方法一:排序

由於互爲字母異位詞的兩個字符串包含的字母相同,因爲對兩個字符串分別進行排序之後得到的字符串一定是相同的,故可以將排序之後的字符串作爲哈希表的鍵。

class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        mp = collections.defaultdict(list) # 定義哈希表

        for st in strs:
            key = "".join(sorted(st)) # 字符串排序,作爲字典key
            mp[key].append(st) # 鍵爲排序後的字符串,值爲原始字符串

        return list(mp.values()) # 返回list格式的字典的值即可

# 時間複雜度:O(nklogk)。其中n是strs中的字符串的數量,k是strs中的字符串的最大長度。需要遍n個字符串,對於每個字符串,需要O(klogk)的時間進行排序以及O(1)的時間更新哈希表,因此總時間複雜度是O(nklogk)
# 空間複雜度:O(nk)。n是strs中字符串的數量,k是strs中字符串的最大長度。需要用哈希表存儲全部字符串。

方法二:計數

由於互爲字母異位詞的兩個字符串包含的字母相同,因此兩個字符串中的相同字母出現的次數一定是相同的,故可以將每個字母出現的次數使用字符串表示,作爲哈希表的鍵。

由於字符串只包含小寫字母,因此對於每個字符串,可以使用長度爲26的數組記錄每個字母出現的次數。需要注意的是,在使用數組作爲哈希表的鍵時,不通語言的支持程度不同,因此不同語言的實現方式也不同。

class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        mp = collections.defaultdict(list)

        for st in strs:
            counts = [0] * 26
            for ch in st:
                counts[ord(ch) - ord("a")] += 1
            # 需要將 list 轉換成 tuple 才能進行哈希
            mp[tuple(counts)].append(st)
        
        return list(mp.values())

 

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