49.字母异位词分组
题目要求
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
示例 1:
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
示例 2:
输入: strs = [""]
输出: [[""]]
示例 3:
输入: strs = ["a"]
输出: [["a"]]
解题答案和思路
这种方法的核心思想是使用哈希表,将字母异位词映射到同一个键,然后将它们分组在一起。
- 创建一个HashMap(哈希表)用于存储字母异位词分组的结果。在这个哈希表中,键是排序后的字符串,值是该组字母异位词的列表。我们使用排序后的字符串作为键,因为字母异位词排序后应该是相同的,这样可以确保它们被映射到同一个键下。
- 遍历给定的字符串数组
strs
,对于每个字符串str
,执行以下步骤:- 将字符串
str
转换成字符数组charArray
。 - 对字符数组
charArray
进行排序,将其转换回字符串sortedStr
。这一步是为了确保具有相同字母的字符串在排序后都变成了相同的字符串,从而能够映射到相同的键上。 - 检查哈希表中是否已经存在键为
sortedStr
的项。如果不存在,就创建一个新的键值对,其中键为sortedStr
,值为一个新的空列表。 - 将当前原始字符串
str
添加到键为sortedStr
的值(列表)中。
- 将字符串
- 遍历哈希表的值,将每个值(即字母异位词组)添加到结果列表中。这样,最终结果就是一组包含字母异位词分组的列表。
为了更清晰地理解这个过程,让我们通过一个示例来说明:
假设输入的字符串数组strs
为:[“eat”, “tea”, “tan”, “ate”, “nat”, “bat”]。
-
对每个字符串进行处理:
- “eat” 变为 “aet”
- “tea” 变为 “aet”
- “tan” 变为 “ant”
- “ate” 变为 “aet”
- “nat” 变为 “ant”
- “bat” 变为 “abt”
-
哈希表的内容将如下所示:
jsonCopy code{ "aet": ["eat", "tea", "ate"], "ant": ["tan", "nat"], "abt": ["bat"] }
-
最后,将哈希表的值取出并放入结果列表中:
cssCopy code[ ["eat", "tea", "ate"], ["tan", "nat"], ["bat"] ]
这样,我们成功将字母异位词分组在了一起。这种方法的时间复杂度是O(N * K * logK),其中N是字符串数组的长度,K是字符串的平均长度。这是因为在遍历字符串数组时,对每个字符串进行排序需要O(K * logK)的时间复杂度。
解题代码:
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> anagramGroups = new HashMap<>();
for (String str : strs) {
char[] charArray = str.toCharArray();
Arrays.sort(charArray);
String sortedStr = new String(charArray);
if (!anagramGroups.containsKey(sortedStr)) {
anagramGroups.put(sortedStr, new ArrayList<>());
}
anagramGroups.get(sortedStr).add(str);
}
return new ArrayList<>(anagramGroups.values());
}
}