手摸手提桶跑路——LeetCode49. 字母异位词分组

90 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 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 <= 104
  • 0 <= strs[i].length <= 100
  • strs[i] 仅包含小写字母

解题思路

通过题目我们可以知道,两个长度相等的字符串,每个字母的数量也相等,只要满足这两个条件,那么就称这两个词为异位词。

比如 eattea,这两个单词中,各自 e 的数量为1,a 的数量为1,t 的数量为1,它们的长度都为3,满足上述的两个条件,因此它俩是异位词。

那么我们就有了初步的思路了,我们对每个单词的字母都计数,最后比对这个计数,相同的就是异位词,合并到一起,最后的结果就是答案了。这个思路可行是可行,但是仔细一想就知道它的效率 极低 了,每个字符之间都要比对,很费时的,所以我们要找别的办法。

看看 eattea 这两个单词,明明长的挺像,但就是不一样,那么有没有什么办法让它们变得一样呢?不管是都变成 eat 还是 ate,或者是 tea,什么都可以,能变成一样的就好。

聪明的小伙伴应该想到了,对两个长度且各种字母数量相同的字符串进行 排序,排序后两个字符串一定是相同的。

我们可以用一个 hashmap 来计数,用排序后的字符串 skey,初始值为 [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());
};

捕获.PNG