携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第29天,点击查看活动详情
题目描述
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。
示例 1:
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
示例 2:
输入: strs = [""]
输出: [[""]]
示例 3:
输入: strs = ["a"]
输出: [["a"]]
提示:
1 <= strs.length <= 1040 <= strs[i].length <= 100strs[i]仅包含小写字母
解题思路
通过题目我们可以知道,两个长度相等的字符串,每个字母的数量也相等,只要满足这两个条件,那么就称这两个词为异位词。
比如 eat 和 tea,这两个单词中,各自 e 的数量为1,a 的数量为1,t 的数量为1,它们的长度都为3,满足上述的两个条件,因此它俩是异位词。
那么我们就有了初步的思路了,我们对每个单词的字母都计数,最后比对这个计数,相同的就是异位词,合并到一起,最后的结果就是答案了。这个思路可行是可行,但是仔细一想就知道它的效率 极低 了,每个字符之间都要比对,很费时的,所以我们要找别的办法。
看看 eat 和 tea 这两个单词,明明长的挺像,但就是不一样,那么有没有什么办法让它们变得一样呢?不管是都变成 eat 还是 ate,或者是 tea,什么都可以,能变成一样的就好。
聪明的小伙伴应该想到了,对两个长度且各种字母数量相同的字符串进行 排序,排序后两个字符串一定是相同的。
我们可以用一个 hashmap 来计数,用排序后的字符串 s 做 key,初始值为 [s],后续有 排序后的字符串 命中该 key 的,就把 s的原字符串 加入到 value 数组中。
题解
/**
* @param {string[]} strs
* @return {string[][]}
*/
var groupAnagrams = function(strs) {
if(strs.length == 1) {
if(!strs[0]) return [['']];
return [[strs[0]]]
};
const map = new Map();
for(let str of strs) {
let key = Array.from(str).sort().toString();
map.set(key, map.has(key) ? map.get(key).concat(str) : [str]);
}
return Array.from(map.values());
};