🚩传送门:力扣题目
题目
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。
示例 1:
输入: strs = [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”] 输出: [[“bat”],[“nat”,”tan”],[“ate”,”eat”,”tea”]]
解题思路:哈希表
两个字符串互为字母异位词,当且仅当两个字符串包含的字母相同。由于互为字母异位词的两个字符串包含的字母相同,因此对两个字符串分别进行排序之后得到的字符串一定是相同的,故可以将排序之后的字符串作为哈希表的键。
比如
aap
、paa
均包含 2 个a
、1 个p
,排序后均为aap
遍历每个字符串,对于每个字符串排序,得到该字符串所在组的哈希表的键,将当前字符串加入该组字母异位词的列表中。遍历全部字符串之后,哈希表中的每个键值对即为一组字母异位词。
复杂度分析
时间复杂度: ,其中
是
中的字符串的数量,
是
中的字符串的的最大长度。
空间复杂度: ,需要用哈希表存储全部字符串。
官方代码
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);
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());
}
}
两个字符串互为字母异位词,当且仅当两个字符串包含的字母相同。所以每个单词包含的字符数量是一致的,我们使用保存单词所有字符的次数,作为
,
作为
存储。
我的代码
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
// map 做 key 统计 str 中各个字符出现的次数,List放入str
// value 是list,所有字符次数一致即一组异位词的放一起
HashMap<HashMap<Character,Integer>,List<String>>map=new HashMap<>();
for(String str:strs){
HashMap<Character,Integer> count=new HashMap<>();
// 统计当前单词所有字符出现的次数
for (int i = 0; i < str.length(); i++) {
count.put(str.charAt(i),count.getOrDefault(str.charAt(i),0)+1);
}
List<String> list=new LinkedList<>();
// 将当前单词添加到异位词组list里
if(map.containsKey(count)){
list=map.get(count);
list.add(str);
map.put(count,list);
}
else{
list.add(str);
map.put(count,list);
}
}
List<List<String>> res=new LinkedList<>();
for(Map.Entry<HashMap<Character,Integer>,List<String>>entry:map.entrySet()){
res.add(entry.getValue());
}
return res;
}
}