题目描述
49. 字母异位词分组
给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
示例:
输入: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”]
输出:
[
[“ate”,“eat”,“tea”],
[“nat”,“tan”],
[“bat”]
]
说明:
所有输入均为小写字母。
不考虑答案输出的顺序。
分析:
具有相同字母的不同字符串分为一组。
解法一:将每个字符串都进行排序,然后存入Map中,比如 tea, eat排序之后都为aet,映射到同一组key中
解法二:写一个方法使得具有相同字母的字符串的key 值为同一个
代码实现
方法一: 在力扣上AC这道题没必要使用LinkedHashMap,但是当我做中兴的笔试题的时候发现输出的顺序需要与输入的顺序一致,因此使用了LinkedHashMap
public class Test4 {
public static void main(String[] args) {
String strs[]= {"abcd","dsfg","gsfd","bacd"};
List<List<String> > lists=func(strs);
for(List<String> list:lists) {
for(String str:list) {
System.out.print(str+" ");
}
System.out.println();
}
}
public static List<List<String> > func(String[] strs){
List<List<String> > lists=new ArrayList<>();
if(strs==null||strs.length<=0) {
return lists;
}
Map<String,List> map=new LinkedHashMap<>();
for(String s:strs) {
char[] arr=s.toCharArray();
Arrays.sort(arr);
String tmp=String.valueOf(arr);
if(!map.containsKey(tmp)) {
map.put(tmp, new ArrayList<String>() );
}
map.get(tmp).add(s);
}
for(List<String> list:map.values()) {
lists.add(list);
}
return lists;
}
}
方法二:为同类(具有相同字母不同顺序)的字符串创建相同的key
这里最主要的就是如何获取这个key.
这里参考力扣题解 详细通俗的思路分析,多解法中提到的方案
算术基本定理,又称为正整数的唯一分解定理,即:每个大于1的自然数,要么本身就是质数,要么可以写为2个以上的质数的积,而且这些质因子按大小排列之后,写法仅有一种方式。
也就是说将每一个字母映射到一个质数上,那么同类字母的乘积均为同一个值。
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
List<List<String> > lists=new ArrayList<>();
if(strs==null||strs.length<=0){
return lists;
}
// Map<String,List<String> > map=new HashMap<>();
Map<Long,List<String> > map=new HashMap<>();
for(String str:strs){
// char[] arr=str.toCharArray();
// Arrays.sort(arr);
// String key=String.valueOf(arr);
long key=getKey(str);
if(!map.containsKey(key)){
map.put(key,new ArrayList<String>());
}
map.get(key).add(str);
}
for(List<String> list:map.values()){
lists.add(list);
}
return lists;
}
public long getKey(String str){
long hashCode=1;
int[] prime = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103 };
char[] arr=str.toCharArray();
for(char ch:arr){
hashCode*=prime[ch-'a'];
}
return hashCode;
}
}