一、题目描述
编写一种方法,对字符串数组进行排序,将所有变位词组合在一起。变位词是指字母相同,但排列不同的字符串。
(题目来源:力扣(LeetCode))
示例:
输入: ["eat", "tea", "tan", "ate", "nat", "bat"],
输出:
[
["ate","eat","tea"],
["nat","tan"],
["bat"]
]
说明:
所有输入均为小写字母。
不考虑答案输出的顺序
二、解决方法
- 字符排序
package com.lxf.test;
import java.util.*;
public class GroupAnagrams {
public static void main(String[] args) {
List<List<String>> lists = groupAnagrams(new String[]{
"cab","tin","pew","duh","may","ill","buy","bar","max","doc"});
for (List<String> list : lists) {
System.out.println(list);
}
}
public static List<List<String>> groupAnagrams(String[] strs) {
if (strs==null) {
return null;
}
int length=strs.length;
//新建存储变位词map
Map<String,List<String>> map=new HashMap<>();
for (int i = 0; i < length; i++) {
//将当前字符串中的字符排序
char[] chars = strs[i].toCharArray();
Arrays.sort(chars);
String key=String.valueOf(chars);
//排序完字符串如果是变位词肯定一样
//按key-value(str,List<String>)的形式存储
if(map.get(key)==null){
//如果map中没有该key,则新建
map.put(key,new ArrayList<String>(6));
}
map.get(key).add(strs[i]);
}
return new ArrayList<>(map.values());
}
}
2.计数(官方)
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> map = new HashMap<String, List<String>>();
for (String str : strs) {
int[] counts = new int[26];
int length = str.length();
//记录下字符串所有字符出现的次数
for (int i = 0; i < length; i++) {
counts[str.charAt(i) - 'a']++;
}
// 将每个出现次数大于 0 的字母和出现次数按顺序拼接成字符串,作为哈希表的键
// 实际上就是按考虑字符顺序,从a-z按次数拼接成map的key
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 26; i++) {
if (counts[i] != 0) {
sb.append((char) ('a' + i));
sb.append(counts[i]);
}
}
String key = sb.toString();
List<String> list = map.getOrDefault(key, new ArrayList<String>());
list.add(str);
map.put(key, list);
}
return new ArrayList<List<String>>(map.values());
}
}