算法题-02
给你一个字符串数组,请你将字母异位词组合在一起。可以按任意顺序返回结果列表。
示例 1:
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
解释:
在 strs 中没有字符串可以通过重新排列来形成 "bat"。
字符串 "nat" 和 "tan" 是字母异位词,因为它们可以重新排列以形成彼此。
字符串 "ate" ,"eat" 和 "tea" 是字母异位词,因为它们可以重新排列以形成彼此。
示例 2:
输入: strs = [""]
输出: [[""]]
示例 3:
输入: strs = ["a"]
输出: [["a"]]
提示:
1 <= strs.length <= 104
0 <= strs[i].length <= 100
strs[i] 仅包含小写字母
整体思路:
由于解释我们可以知道,所谓的将字母异位词组合在一起,其实上就是把相同字母包括个数一样的单词放到同一个list数组中去。
我们可以创建一个哈希表map,将key里面写入经过排序后的字符串(因为这些字母异位词中的字母排序过后的顺序都是一样的),value中存储的是对应的原始字符串列表。最后返回所有的value
class Solution {public List<List<String>> groupAnagrams(String[] strs) {Map<String,List<String>> map = new HashMap<>();for(String str : strs){char[] s = str.toCharArray();Arrays.sort(s);if(map.containsKey(new String(s))){map.get(new String(s)).add(str);}else{List<String> temp = new ArrayList<>();temp.add(str);map.put(new String(s),temp);}}return new ArrayList<>(map.values());}
}
将字符串转换成字符数组,对字符数组排序,排序后:"eat" → ['a','e','t'] → "aet","tea" → ['a','e','t'] → "aet",排序的作用:字母异位词排序后都是相同的字符串,便于用作 key
map.containsKey(new String(s)),检查排序后的字符串是否已经存在 key
map.get(new String(s)).add(str),已存在,则把原始字符串加入已有列表
如果 key 不存在:创建新列表 temp,把原始字符串加入列表,放入 map
put 和 get 的区别
put(key, value):用于 插入或覆盖 key 对应的 value
例子:
map.put("aet", new ArrayList<>(Arrays.asList("eat"))); // 创建新列表
map.put("aet", new ArrayList<>(Arrays.asList("tea"))); // 覆盖原列表,变成 ["tea"]
get(key):用于 获取 key 对应的 value
例子:
List<String> list = map.get("aet"); // list = ["eat"]
list.add("tea"); // list = ["eat","tea"]
注意:get(key) 拿到的是 value 的引用,修改引用内部内容不会改变 map 的 key 对应引用本身。
为什么这里用 get 而不是 put
目标:把当前字符串加入已存在的异位词组,而不是创建新的列表或覆盖原有列表。
if(map.containsKey(new String(s))){
map.get(new String(s)).add(str); // 在已有列表里添加元素
} else {
List<String> temp = new ArrayList<>();
temp.add(str);
map.put(new String(s), temp); // key 不存在,创建新列表
}
如果用 put:
map.put(new String(s), new ArrayList<>(Arrays.asList(str)));
每次 put 都会创建一个新的列表,原来的列表被覆盖 → 已有的字母异位词丢失,这就不是我们想要的逻辑了