1.字母异位词分组
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
方法一:字母排序
java
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
// 处理边界情况:如果输入数组为空,直接返回空列表
if (strs.length == 0) return new ArrayList<>();
// 创建哈希表:键为排序后的字符数组(字符串形式),值为该异位词组对应的字符串列表
Map<String, List<String>> map = new HashMap<>();
// 遍历输入的每个字符串
for (String str : strs) {
// 将字符串转换为字符数组,以便进行排序
char[] chars = str.toCharArray();
// 对字符数组进行排序(例如:"eat" → ['a', 'e', 't'])
// 排序后相同异位词的字符数组顺序相同,可作为相同的键
Arrays.sort(chars);
// 将排序后的字符数组转换为字符串,作为哈希表的键
// 例如:['a', 'e', 't'] → "aet"
String key = String.valueOf(chars);
// 检查哈希表中是否已存在该键
// 如果不存在,创建一个新的空列表,并与该键关联
if (!map.containsKey(key)) {
map.put(key, new ArrayList<>());
}
// 将原始字符串添加到对应键的列表中
// 例如:"eat" 和 "tea" 都会被添加到键 "aet" 对应的列表中
map.get(key).add(str);
}
// 将哈希表中的所有值(列表集合)转换为一个大列表并返回
// 每个子列表包含一组互为异位词的字符串
return new ArrayList<>(map.values());
}
}
方法二 字符计数法

时间复杂度和空间复杂度
java
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
// 创建一个哈希表,用于分组异位词
// 键:由字母和出现次数组成的字符串(如 "a1b2")
// 值:所有符合该模式的字符串列表(如 ["abb", "bab", "bba"])
Map<String , List<String>> map =new HashMap<>();
// 遍历输入的每个字符串
for(String str : strs){ // 创建一个长度为26的数组,统计每个字母的出现次数
// counts[0] 对应 'a' 的次数,counts[1] 对应 'b' 的次数,依此类推
int[] counts =new int[26];
int length =str.length();
// 遍历字符串中的每个字符,统计次数
for(int i=0;i<length;i++){
// 将字符转换为数组索引:'a' 变成 0,'b' 变成 1,...,'z' 变成 25
// 对应位置的计数加1
counts[str.charAt(i)- 'a' ] ++;
}
StringBuilder sb = new StringBuilder();
// 生成用于哈希表的键
// 按字母顺序拼接每个出现过的字母及其次数(如 "a1b2")
for(int i= 0 ; i < 26 ; i++ ){
if(counts[i]!= 0){
// 添加字母(如 'a')
sb.append((char)('a'+i));
// 添加该字母的出现次数(如 2)
sb.append(counts[i]);
}
}
String key = sb.toString();
// 将当前字符串添加到对应的分组中
// 如果键不存在,创建一个新的列表
// 如果键已存在,获取已有的列表
List<String> list=map.getOrDefault(key,new ArrayList<>());
list.add(str);
map.put(key,list);
}
// 返回哈希表中所有的值(即所有分组)
return new ArrayList<>(map.values());
}
}