给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。
示例 1:
输入: strs = [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”]
输出: [[“bat”],[“nat”,“tan”],[“ate”,“eat”,“tea”]]
示例 2:
输入: strs = [“”]
输出: [[“”]]
思路:注意,看到这种分组类问题,一定要想到数据结构map,因为map可以很好的完成我们要进行类别统计的任务,也可以根据k分类不同的value。
其实,很直观的解法是暴力解法,我们可以遍历每一个字符串数组中的字符串,然后用int数组统计里面字母以及字母的个数。将这个数组和list中的每一个数组比较,如果相等,就将其存入到本次相比的列表中,如果不等就继续循环,如果一直到循环结束还没找到相等的,那就说明目前列表中不存在该字符串的字母异位词,就将该字符串自己作为一个列表存入到大列表中。
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
if(strs.length == 0){
return new ArrayList<List<String>>();
}
if(strs.length == 1){
ArrayList<String> l = new ArrayList<>();
l.add(strs[0]);
List<List<String>> l1 = new ArrayList<List<String>>();
l1.add(l);
return l1;
}
List<List<String>> list = new ArrayList<List<String>>();
boolean[] flag = new boolean[strs.length];
for(int i = 0; i < strs.length && flag[i] == false; i++){
if(list.size() == 0){
// List<String> li = new ArrayList<String>(strs[0]);
ArrayList<String> l = new ArrayList<>();
l.add(strs[0]);
// List<List<String>> l1 = new ArrayList<List<String>>();
list.add(l);
}else{
int j = 0;
for(j = 0; j < list.size(); j++){
int[] m = new int[26];
int[] n = new int[26];
String s = list.get(j).get(0);
String s1 = strs[i];
for(int k = 0; k < s.length(); k++){
m[s.charAt(k) - 'a'] += 1;
}
for(int k = 0; k < s1.length(); k++){
n[s1.charAt(k) - 'a'] += 1;
}
if(Arrays.equals(m,n)){
list.get(j).add(s1);
break;
}
}
if(j == list.size()){
// list.add(new ArrayList<>(strs[i]));
ArrayList<String> l3 = new ArrayList<>();
l3.add(strs[i]);
// List<List<String>> l1 = new ArrayList<List<String>>();
list.add(l3);
}
}
}
return list;
}
}
但是,这种暴力解法复杂度极高,我们应该想办法优化解法。下面就介绍进一步使用map数据结构的解法。
字母异位词也就是两串字符串除了顺序其它都一样,并且每个字母只用一次,这个信息很重要。有了这个信息,我们就可以认为,每个字符串排序后是可以作为评判是否是异位词的标准的。因此我们可以将每个字符串都取出来,然后转化为字符数组,对字符数组内元素进行排序,然后用排好序的字符数组形成的字符串作为标识,寻找和它一样的字符串,这两个字符串就是字母异位词。显然,这就需要map数组,将排好序的字符数组形成的字符串作为标识key,后面value值是一个列表,存放和这个标识相同的所有字母异位词的列表。
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, ArrayList<String>> map = new HashMap<>();
for (String str : strs) {
char[] chars = str.toCharArray();
Arrays.sort(chars);
String key = new String(chars);
if (!map.containsKey(key)) {
map.put(key, new ArrayList<>());
}
map.get(key).add(str);
}
return new ArrayList<>(map.values());
}
}