LeetCode HOT 100:字母异位词分组
题目:49. 字母异位词分组
题目描述:
给你一个字符串数组,字符串只包含小写字母。要将数组中的字母异位词
进行分组。解释一下什么叫字母异位词
。假设有几个字符串,除了字符串中的字符顺序不同,其他都相同,这就叫互为字母异位词
。例如abc
和acb
,他们互为字母异位词
。但是如果abc
和ab
,就不是。进行分组什么意思呢?就是把互相是字母异位词
的都划分到一组,如果没有和别的字符串成字母异位词
,那自己就是一组。最终返回所有组,不分先后顺序。
思路:
这一题思路其实很简单,所谓字母异位词
换个角度想一下就是经过某些处理之后一样的字符串。比如排序,或者统计每个字母出现频率,组成新的字符串(这种处理得要求字符串中只有小写字母),这两种处理都可以让互为字母异位词
的字符串返回一样的字符串。然后将处理过的字符串当成key
,处理之后能得到key
的原字符串放进一个集合中当做value
,最终返回所有的value
,即可得出答案。下面的步骤是排序
处理的步骤,两种处理方式整体差不多。
步骤:
1、遍历字符串数组,拿到其中的某一个字符串
2、将该字符串排序,去Map
中找有没有该字符串,如果有,直接将原字符串存进集合,没有则创建新集合,将原字符串存进去
3、最终返回Map
的values
集合即可
代码:
第一种处理代码:
// 直接排序,将排序之后的字符串当key
public List<List<String>> groupAnagrams1(String[] strs) {
Map<String, List<String>> map = new HashMap<>();
for (String str : strs) {
char[] chars = str.toCharArray();
Arrays.sort(chars);
String sortStr = new String(chars);
if (map.containsKey(sortStr)) {
map.get(sortStr).add(str);
} else {
List<String> groupList = new ArrayList<>();
groupList.add(str);
map.put(sortStr, groupList);
}
}
return new ArrayList<>(map.values());
}
第二种处理代码:
// 将字符串中字符出现的频率转化成新的字符串,当做key
// 例如:[b,a,a,a,b,c],转化为 a3b2c1
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> map = new HashMap<>();
for (String str : strs) {
int[] counts = new int[26];
for (char ch : str.toCharArray()) {
counts[ch - 'a']++;
}
StringBuilder builder = new StringBuilder();
for (int i = 0; i < counts.length; i++) {
if (counts[i] != 0) {
builder.append((char) (i + 'a'));
builder.append(counts[i]);
}
}
String key = builder.toString();
List<String> list = map.getOrDefault(key, new ArrayList<>());
list.add(str);
map.put(key, list);
}
return new ArrayList<>(map.values());
}