给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
方法一:计数(性能差)
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
// 对每个字符串,首先统计这个字符串中出现26个字母的次数,用一个int[26]数组表示
// 然后将该字符串的int[26]数组转换为a5b4c7...这种形式,作为map的key
// 字母异位词的key是一样的,然后map的值List<String>就是这些原词
Map<String,List<String>> map = new HashMap<String,List<String>>();
for(String str:strs){
int[] counts = new int[26];
int length = str.length();
for(int i=0;i<length;i++){
// 如果str="abc" charAt[0]='a' charAt[1]='b'
counts[str.charAt(i) - 'a']++; // 核心代码
// aabz =》 counts[0]=2 counts[1]=1 counts[25]=1
}
// 将每个出现次数大于 0 的字母和出现次数按顺序拼接成字符串,作为哈希表的键
// aabz => counts[0]=2 counts[1]=1 counts[25]=1 => a2b1z1
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();
// getOrDefault方法:
//Map集合中有这个key时,就使用这个key对应的value值,如果没有就使用默认值defaultValue
List<String> list = map.getOrDefault(key, new ArrayList<String>());
list.add(str);
map.put(key,list);
}
return new ArrayList<List<String>>(map.values());
}
}
方法二:排序(性能好)
class Solution {
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(); // 将字符串转化为字符数组
Arrays.sort(array); // 字符数组排序,a在最前 z在最后
String key = new String(array); // 将字符数组转化为字符串
List<String> list = map.getOrDefault(key, new ArrayList<String>());
list.add(str);
map.put(key, list);
}
return new ArrayList<List<String>>(map.values());
}
}