leetcode 49. 字母异位词分组
中等题
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次
示例
示例 1:
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
示例 2:
输入: strs = [""]
输出: [[""]]
示例 3:
输入: strs = ["a"]
输出: [["a"]]
题解
首先第一想法就是需要建立哈希表,key记录一组字母异位词的共同特征,value则是具体的异位词;
两种思路:
- 单词排序的结果作为key
- 26位单词表字母出现的个数计数
排序
class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
result = collections.defaultdict(list) #value初始化使用list
for s in strs:
ts = ''.join(sorted(s))
result[ts].append(s)
return list(result.values())
- 时间复杂度:这种方式的时间复杂度为 O ( n k l o g k ) O(nklogk) O(nklogk),k表示最大的字母长度。对于每个字符串,需要 O ( k l o g k ) O(klogk) O(klogk)的时间进行排序以及 O ( 1 ) O(1) O(1)的时间更新哈希表,因此总时间复杂度是 O ( n k l o g k ) O(nklogk) O(nklogk)
- 空间复杂度:O(nk),其中 n 是 strs 中的字符串的数量,k 是 strs 中的字符串的的最大长度。需要用哈希表存储全部字符串
计数
class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
#计数 O(n(k+∣Σ∣))
result = collections.defaultdict(list)
for s in strs:
counts = [0]*26
for c in s:
counts[ord(c)-ord('a')]+=1
result[tuple(counts)].append(s) #list无法作为key需要转化为tuple
#O(∣Σ∣)的时间生成哈希表的键
return list(result.values())
-
时间复杂度:O(n(k+∣Σ∣)),∣Σ∣=26|。需要遍历 n 个字符串,对于每个字符串,需要 O(k) 的时间计算每个字母出现的次数,O(∣Σ∣)的时间生成哈希表的键,以及 O(1) 的时间更新哈希表,因此总时间复杂度是 O(n(k+∣Σ∣))。
-
空间复杂度:O(n(k+∣Σ∣)),需要用哈希表存储全部字符串,而记录每个字符串中每个字母出现次数的数组需要的空间为 O(∣Σ∣)。