力扣49.字母异位词分组
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
示例 1:
输入: strs = [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”]
输出: [[“bat”],[“nat”,“tan”],[“ate”,“eat”,“tea”]]
示例 2:
输入: strs = [“”]
输出: [[“”]]
示例 3:
输入: strs = [“a”]
输出: [[“a”]]
方法一
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> map = new HashMap<String, List<String>>();
for(String str:strs){
char[] array = str.toCharArray();
// 对字符数组进行排序,['e','a','t']排序为['a','e','t']
Arrays.sort(array);
// 将排序后的字符数组转换回字符串,作为哈希映射的键,将aet作为key来使用
String key = new String(array);
// 从哈希映射中获取键对应的异位词列表,如果不存在则返回一个新的列表
// 从map中获取key为aet的值,由于第一个不存在,所以默认将字符数组中的eat添加到空列表list中
List<String> list = map.getOrDefault(key,new ArrayList<String>());
// 将当前字符串添加到异位词列表中
// 现在list = ["eat"],eat的key是ate,key ate的值value是eat
list.add(str);
// 将异位词列表放回哈希映射中
map.put(key,list);
}
// 将哈希映射中的所有值(即所有的异位词列表)转换为一个列表返回
return new ArrayList<List<String>>(map.values());
}
方法二
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> map = new HashMap<String, List<String>>();
// 遍历每一个字符串
for (String str : strs) {
// 26个字母设置26长度的数组,假设第一个是eat
int[] counts = new int[26];
// eat的字符长度为3
int length = str.length();
// 遍历当前字符串,更新字符计数数组
// 这里的意思是遍历eat,计算出e对应的索引值4(4是e的那个ASCII码减去a的ASCII码为4),对应的数字个数是1
// 即counts[4]所对应的值是1,而a是counts[0]对应1,t是counts[19]对应1
for (int i = 0; i < length; i++) {
counts[str.charAt(i) - 'a']++;
}
// 创建一个字符串缓冲区,用于构建字符计数字符串
// 将每个出现次数大于 0 的字母和出现次数按顺序拼接成字符串,作为哈希表的键,即key为a1e1t1对应的values值是eat
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 26; i++) {
if (counts[i] != 0) {
sb.append((char) ('a' + i));
sb.append(counts[i]);
}
}
// 将字符计数字符串作为哈希映射的键
String key = sb.toString();
// 接下来就和法一类似,以此类推
List<String> list = map.getOrDefault(key, new ArrayList<String>());
list.add(str);
map.put(key, list);
}
return new ArrayList<List<String>>(map.values());
}