一、题目描述
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。
示例一
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
示例二
输入: strs = [""]
输出: [[""]]
二、解题思路
(1)先将字符串数组中的每一个字符串排序,那么由相同字符组成的不同字符串在排序后必定相同
(2)然后二重循环,将已经内部排好序的字符串进行分组(有更好的做法可以代替此步)
三、代码
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
List<List<String>> targetListStr = new ArrayList<>();
int len = strs.length;
//如果数组长度为0,直接返回Null
if (len == 0) {
return targetListStr;
}
List<String> assistListStr = new ArrayList<>();
//如果只有一个字符串,则直接添加
if (len == 1) {
assistListStr.add(strs[0]);
targetListStr.add(assistListStr);
return targetListStr;
}
//assistListStr存储已排序字符串
for (String str : strs) {
assistListStr.add(sortStr(str));
}
//两重循环遍历string数组,相同的放在一起即可
ArrayList<String> temp = new ArrayList<>();
boolean[] used = new boolean[len];
for (int i = 0; i < len; i++) {
temp = new ArrayList<>();
//当前字符串没使用过,则装入集合,否则进入下一次循环
if (!used[i]) {
temp.add(strs[i]);
used[i] = true;
}else {
continue;
}
//判断后面的字符串是否与当前assistListStr.get(i)相同,相同则装入字符串数组
for (int j = i + 1; j < len; j++) {
if (assistListStr.get(i).equals(assistListStr.get(j))) {
temp.add(strs[j]);
used[j] = true;
}
}
if (temp.size() != 0) {
targetListStr.add(temp);
}
}
return targetListStr;
}
//字符串排序函数
public String sortStr(String str) {
char[] strArray = str.toCharArray();
Arrays.sort(strArray);
return new String(strArray);
}
}
四、更好解题方法
因为涉及到集合中有相同元素且相同元素归位一类,所以应该想到用哈希。
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);
//如果map中存在当前key,则取出其对应的List<String>;否则,当前List赋值为null
List<String> list = map.getOrDefault(key, new ArrayList<String>());
//字符串添加到list
list.add(str);
//修改的list放到map中
map.put(key, list);
}
return new ArrayList<List<String>>(map.values());
}
}