数据小用数组,数据大用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.返回所有的分组结果,就是整个字符串