题目
给定一个字符串数组 strs
,将 变位词 组合在一起。 可以按任意顺序返回结果列表。
注意:若两个字符串中每个字符出现的次数都相同,则称它们互为变位词。
示例 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]
仅包含小写字母
注意:本题与主站 49 题相同: 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
LCR 033. 字母异位词分组 - 力扣(LeetCode)
题解
思路一:有问题,在迭代器(map)迭代的过程中不能删除元素,否则会报错。
代码:
public List<List<String>> groupAnagrams(String[] strs) {
Map<String,int[]> sums=new HashMap<String, int[]>();
for(String s:strs) {
int[] sum=new int[26];
for(int i=0;i<s.length();i++) {
sum[s.charAt(i)-'a']++;
}
sums.put(s,sum);
}
List<List<String>> result = new ArrayList<List<String>>();
for(String s : sums.keySet()) {
int[] tmp=sums.get(s);
List<String> result2 = new ArrayList<String>();
result2.add(s);
sums.remove(s);
//运行时会报错,循环过程中修改map不好改
for(String s2:sums.keySet()) {
int[] tmp2=sums.get(s2);
for(int i=0;i<26;i++) {
if(tmp[i]!=tmp2[i]) break;
}
result2.add(s2);
sums.remove(s2);
}
result.add(result2);
}
return result;
}
思路二:使用排序(适用于String都不长时使用)
代码:
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());
}
}
思路三:计数。
关键在于提取总结出sums<String,int[]>后如何进行
1.判断int[]相等。设计一个简单的hash函数代替遍历map的查询对比,将int[]转换成long或者拼接成str,例如key+=key*10+int[i]。这时可以map<String或者Long,List<String>>,使用hash值和列表对应。
2.能找到对应的String。不要想先将String转化成map再操作,在第一个迭代循环内就对应完成result的add
代码:
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String,List<String>> result = new HashMap<String, List<String>>();
for(String s:strs) {
int[] sum=new int[26];
for(int i=0;i<s.length();i++)
sum[s.charAt(i)-'a']++;
StringBuffer sb = new StringBuffer();
for(int j=0;j<26;j++) {
//这个hash是有问题的,都是0101,有重复的可能。加入字母则不会
//sb.append(sum[j]);
if(sum[j]!=0) {
sb.append(j+'a');
sb.append(sum[j]);
}
}
String str=sb.toString();
List<String> sresult=result.getOrDefault(str, new ArrayList<String>());
sresult.add(s);
result.put(str, sresult);
}
return new ArrayList<List<String>>(result.values());
}
}
sb.append(sum[j])的hash不对。["bdddddddddd","bbbbbbbbbbc"]
都是01010,因为append的时候10加进来是“10”而不是“01”,所以不是从右往左的。若从右往左加,可以考虑使用long型,key+=key*10+sum[j]。