问题描述:
Given an array of strings, group anagrams together.
For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"]
,
Return:
[ ["ate", "eat","tea"], ["nat","tan"], ["bat"] ]
Note:
- For the return value, each inner list's elements must follow the lexicographic order.
- All inputs will be in lower-case.
原问题链接:https://leetcode.com/problems/anagrams/
问题分析
这个问题其实相对来说比较简单,因为它本身的要求是将一些包含相同字符的词组合在一起,并且是排序的。这里的难点在于第一步,怎么将这些包含有相同个数字符的词放在一起。因为它们由相同的字符集合构成,仅仅是因为排列的顺序不一样。
其实这一类anagram的问题有一个固定的解决套路,虽然它们这些字符集构成的词有千变万化,但是既然是相同的词,我们将一个词里所有的字符首先排序得到一个字符串数组对于所有anagram来说就是一样的。所以我们可以将一个词里所有字符构成的串排序,然后将这个结果作为key,所有相同结果的词都放到同一个key下面。这样我们就可以很自然的想到用一个Map来解决问题。
在详细的实现时,我们可以声明一个HashMap<String, List<String>>,key是根据一个字符串排序后得到的一个串,value是相同的anagram构成的列表。因为要求后面的结果是排序的,我们在后面将所有的value值都从Map里取出来的时候,先对value排一下序再加入到最终的列表中即得到最终的结果。详细实现如下:
public class Solution { public List<List<String>> groupAnagrams(String[] strs) { List<List<String>> result = new ArrayList<>(); Map<String, List<String>> map = new HashMap<>(); for(String s : strs) { char[] chars = s.toCharArray(); Arrays.sort(chars); String key = String.valueOf(chars); if(!map.containsKey(key)) map.put(key, new ArrayList<>()); map.get(key).add(s); } for(String key : map.keySet()) { List<String> list = map.get(key); Collections.sort(list); result.add(list); } return result; } }