【LeetCode】每日一题 字母异位词分组

80 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第23天,点击查看活动详情

49. 字母异位词分组

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。

「示例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] 仅包含小写字母

解题思路

// 第一种
思路:遍历字符串数组,对每个字符串中的字符排序,加入map对应的key的数组中。
复杂度:时间复杂度O(n*klogk),n是字符串的个数,k是最长的字符串的长度,排序复杂度O(klogk),n次排序,哈希表更新O(1)。空间复杂度O(nk),排序空间复杂度O(nlogk),map空间复杂度O(nk),取较大的O(nk)
​
// 第二种
思路:题意是字符串的字符都是小写,可以对每个字符串统计其中字符的频次,将每个字符频次相同的字符串放在一组
复杂度:时间复杂度O(n*k),n是字符串个数,k是最长字符串长度,循环字符串数组复杂度O(n),对每个字符串统计频次复杂度O(k)。空间复杂度O(n*k),map中存放了n个大小最长为k的字符串。

代码实现

// 第一种
var groupAnagrams = function(strs) {
    const map = new Map();
    for (let str of strs) {
        let array = Array.from(str);//字符转成数组
        array.sort();//排序
        let key = array.toString();
        let list = map.get(key) ? map.get(key) : new Array();//从map中取到相应的数组
        list.push(str);//加入数组
        map.set(key, list);//重新设置该字符的数组
    }
    return Array.from(map.values());//map中的value转成数组
};
​
// 第二种
var groupAnagrams = function(strs) {
    const map = {};
    for (let s of strs) {//循环字符串数组
        const count = new Array(26).fill(0);//字符都是小写,初始化大小为26的数组
        for (let c of s) {//对字符串的每个字符统计频次
            count[c.charCodeAt() - 'a'.charCodeAt()]++;
        }
        map[count] ? map[count].push(s) : map[count] = [s];//加入map
    }
    return Object.values(map);
};

如果你对这道题目还有疑问的话,可以在评论区进行留言;