方法之一:HashMap+List
解题思路:
- 首先拿到这个题,我们要明确题目的意思,要我们求什么。 分析可知,我们需要求哪些单词是由相同的字母按照不同顺序排列而成的,并把它们展示为一个列表;观察示例可知,列表的每个元素也是一个列表(观察自动生成的Java方法头也可以得知)
- 其次,我们需要联想学过的知识并且思考解题思路。比如List相关知识、Map相关知识、String相关操作、集合操作等。
- 之后,是贴主的解题思路:可以先用循环遍历strs,取出每一个元素,者每一个元素都是一个单词,然后利用Arrays类方法把这些单词都转换为char类型的数组存储起来;只要把这些char数组排序,无论是升序还是降序,只要排列出来的数组一比较是一样的,说明原来的单词是我们所求的同分异构组单词;因此,我们只需要把排序前的Char数组重新转换为字符串,并且以它为键,以遍历出来的字母为键对应的值,就可以把同分异位词分开。
- 流程演示:比如
输入: strs =["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
- 按照我们的思路,遍历strs,得到String类型的i,i[0]="eat",i[1]="tea",i[2]="tan",i[3]="ate",i[4]="nat",i[5]="bat"(此处及以下的下标仅仅标识循环是在第几轮,轮数从0开始,不表示一直连续存储形成了二维数组)
- 转换为Char字符数组arr[0]=e a t arr[1]=t e a arrr[2]=t a n arr[3]=a t e arr[4]=n a t arr[5]=b a t
- 排序后:arr[0]=a e t arr[1]=a e t arr[2]=a n t arr[3]=a e t arr[4]=a n t arr[5]=a b t
- String key: key[0]=aet key[1]=aet key[2]=ant key[3]=aet key[4]=ant key[5]=abt
- GetOrDefault: key[0]=aet做键,i[0]="eat"做值 key[1]=aet做键,i[1]="tea"做值 key[2]=ant做键,i[2]="tan"做值 key[3]=aet做键,i[3]="ate"做值 key[4]=ant做键,i[4]="nat"做值 key[5]=abt做键,i[5]="bat"做值
- aet做键的时候,其值有"eat" "tea" "ate" ant做键时,其值有"tan" "nat" abt做键时,其值有"bat"
下面放上求解代码:
可以看出虽然解释了一堆但是代码还是比较短小的,主要是思路的问题,很多人(包括贴主)刚拿到题目的时候都会卡在某个地方,比如Map的值可以是一个List,还有map的getOrDefault方法,这个确实是到知识盲区了(也许我知识盲区挺大的),所以就卡在这块儿了。
有几点同学可能不是特别理解,贴主根据自己有限的知识解释一下:
public List<List<String>> groupAnagrams(String[] strs) {
: 是方法的声明,指定了方法名为groupAnagrams
,参数为一个字符串数组strs
,返回类型是List<List<String>>
,表示一个列表,其中每个元素也是一个列表,其中包含字符串。
Map<String,List<String>> map=new HashMap<String,List<String>>();
: 在方法内部创建了一个HashMap
对象,用于存储异位词的分组结果。键为异位词的排序后的形式,值为包含该异位词分组的列表。
Arrays.sort(arr);
: 使用Arrays.sort
方法对字符数组arr
进行排序,这样可以确保具有相同字母但顺序不同的字符串排序后相同。
map.getOrDefault(key, defaultValue)
方法用于获取指定键key
对应的值 如果map
中包含键key
,则返回与该键关联的值。如果map
中不包含键key
,则返回defaultValue
指定的值。
map.put(key,list);
: 将更新后的键值对放入map
中,如果已经存在该键,则会覆盖原有的值。
return new ArrayList<List<String>>(map.values());
: 返回一个新的列表,其中包含map
中所有值(分组后的列表),这样就实现了将异位词分组的目的。