文章目录
- 题目描述
- 分析
-
- 示例 1
- 示例 2
- 示例 3
- 提示
- 方法一:先排序后哈希
-
- 思路
- 代码
- 时间复杂度
- 方法二:先计数后哈希
-
- 思路
- 代码
- 时间复杂度
题目描述
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词是由重新排列源单词的所有字母得到的一个新单词。
分析
解题关键在于,如何使得不同的字母异位词有相同的key值,让字母异位词进入到同一个哈希桶中。
示例 1
输入: strs = [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”]
输出: [[“bat”],[“nat”,“tan”],[“ate”,“eat”,“tea”]]
示例 2
输入: strs = [""]
输出: [[""]]
示例 3
输入: strs = [“a”]
输出: [[“a”]]
提示
1 <= strs.length <= 104
0 <= strs[i].length <= 100
strs[i] 仅包含小写字母
方法一:先排序后哈希
思路
- 先将字符串转化为字符数组对其进行排序,那么字母异位词的哈希结果应当是相同的。
- 对排序后数组使用Arrays类的hashCode方法
(简要描述一下hashCode方法:他与数组的长度、顺序都有关,最后返回一个int类型的值)
代码
//排序后哈希
class Solution1 {
public List<List<String>> groupAnagrams(String[] strs) {
HashMap<Integer, List<String>> map = new HashMap<>();
List<List<String>> ans = new ArrayList<>();//用于保存答案
for(String s : strs){
Integer key = getHashKey(s);
if(map.containsKey(key)){
map.get(key).add(s);
}else{
List<String> list = new ArrayList<>();
list.add(s);
map.put(key, list);
}
}
for (Integer key : map.keySet()){
ans.add(map.get(key));
}
if (ans.isEmpty()){
List<String> empty = new ArrayList<>();
empty.add("");
ans.add(empty);
}
return ans;
}
/**
* 获取hash key
* @param s 字符串
* @return hash key
*/
//这个哈希函数能保证有相同的字母就返回相同的哈希值
public Integer getHashKey(String s) {
char[] temp = s.toCharArray();
Arrays.sort(temp);
return Arrays.hashCode(temp);
}
}
时间复杂度
O(Nklogk),k为字符串的长度。排序方法用时O(klogk),总共N个,大致为Nklogk。
方法二:先计数后哈希
思路
- 对于每个字符串对其每个字母的出现次数计数,那么字母异位词的计数结果应当是相同的。
- 利用计数结果进行哈希
代码
//计数后哈希
class Solution2 {
public List<List<String>> groupAnagrams(String[] strs) {
HashMap<Integer, List<String>> map = new HashMap<>();
List<List<String>> ans = new ArrayList<>();//用于储存最终结果
for(String s : strs){
int[] count = new int[26];
// 遍历当前字符串的每个字符
for (char c : s.toCharArray()){
int temp = c - 'a';
// 对应索引的计数加1
count[temp]++;
}
// 将计数数组转换为哈希码,作为哈希表的键
int key = Arrays.hashCode(count);
List<String> temp = map.getOrDefault(key,new ArrayList<String>());
temp.add(s);
map.put(key,temp);//put方法会自动替换旧值并返回
}
for (int key : map.keySet()){
ans.add(map.get(key));
}
if (ans.isEmpty()){
List<String> temp = new ArrayList<>();
temp.add("");
ans.add(temp);
}
return ans;
}
}
时间复杂度
O(Nk),获取计数结果为O(k);总共有 N个字符串。
有问题欢迎讨论,侵权必改