LeetCode题解:字母异位词分组

40 阅读3分钟

数据小用数组,数据大用set,数据散用map

解法1

Array.from是js的一个方法,可以将类数组对象或者可迭代的对象转换成一个真正的数组,之后用于字符串的拆分

sort()方法就是将数组内的元素进行排序.并返回排序后的数组

字母异位词的意思就是将数组中每个元素的字母拆开,如果其中一个元素的字母组成和另外一个元素的字母组成是一样的,就可以把他们放在一组里面.

例如示例一中的ate和eat和tea一样

代码解释

1.先创建一个map哈希表

2.用一个值去遍历这个字母数组得到每一个数组元素

3.将遍历出来的字符串转换为字符数组,相当于把eat拆开成e,a,t三个字母

4.对拆开的字母进行从小到大的排序按照26个字母表

5.将从小到大排序的字符数组用array中的toString方法转化为字符串

6.检查这个key是否存在于map中,如果存在就获取对应的数组,不存在就创建一个新数组

相当于这段代码

let list;
if (map.get(key)) {
    list = map.get(key);  // 获取已存在的分组
} else {
    list = [];           // 创建新的空分组
}

也是这个算法的核心

为什么要这样做

第一次遇到某个字母组合,如果map中没有这个key值就需要新建一个数组,其中的key值就是从小到大排序的字符数组转化为的字符串

如果存在这个字符串就将这个字符串加入key值对应的数组里面

7.将当前做出判断的字符串加入数组中

8.将更新后的数组重新放回map中对应的key下,在list那一步中将toString后的元素添加到list后

然后在Map里面更新其中的值

// 初始状态:map是空的 {}

let key = "a,e,t";
let list = map.get("a,e,t") ? map.get("a,e,t") : new Array();
// map.get("a,e,t") 返回 undefined(不存在)
// 所以创建新数组:list = []

list.push("eat");  // list = ["eat"]

map.set("a,e,t", list);  
// 现在 map: { "a,e,t" → ["eat"] }

解法2

var groupAnagrams = function(strs) {
    const map = new Object();
    for (let s of strs) {
        const count = new Array(26).fill(0);
        for (let c of s) {
            count[c.charCodeAt() - 'a'.charCodeAt()]++;
        }
        map[count] ? map[count].push(s) : map[count] = [s];
    }
    return Object.values(map);
};

1.创建一个空的对象来存储分组的结果

2.用s遍历整个字符串的数组,并存在s中,可以通过strs[s]来访问元素

3.创建一个数组长度为26,在里面充满0,每一个0代表从a开始到z的位置表,a的下标为0,b的下标为1

4.第一次循环用s遍历了整个数组,并且创建了一个长度为26充满0的数组,

这一次循环用c去遍历存在字符串s里面的每一个字符,取出并赋值给c

5计算字符在字母表中的位置,这段代码c.charCodeAt() - 'a'.charCodeAt()

例如:eat,在第二个循环中的到e,a,t,并依次赋值给c

c.charCodeAt就把第一个e转换成数字,101

'a'.charCodeAt代表把a转换成数字,97

两个值相减得到4,

count[4]++,就在26个0对应的数组中第四个位置加了一,0就变成1,

后面的依次计算

7.这个三元运算符就存储已经经过计算之后的字符串s.如果存在就把这个字符串存在这个数组里面,如果不存在就创建一个新的字符串然后存进去

8.返回所有的分组结果,就是整个字符串