[JS] 字母异位词分组与JS中对象键值特性
题目地址:LeetCode 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]
仅包含小写字母
这道题是一道经典的哈希表应用题,哈希表在这道题里面有两个应用:
- 对于一个单词,建立字母到字母出现次数的映射;
- 对于题目给定的单词数组,需要建立一个 特殊值 到单词组的映射;
其中的 特殊值 应该满足由单词计算得到,且不同的字母异位词的 特殊值 是相同的。
官方题解
/**
* @param {string[]} strs
* @return {string[][]}
*/
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);
};
第一层循环遍历的是词组里的单词。
for(let s of strs){
const count = new Array(26).fill(0);
...
}
一开始我很疑惑,因为对于每一个单词,都新建了一个独立的count
来计算这个单词中各个字母出现的次数。
这里的count
就是上文说到的特殊值,用来判断字母异位词。
在一个单词遍历完所有字母后,count
计算完毕,通过
map[count] ? map[count].push(s) : map[count] = [s];
将 特殊值 相同的单词分为一组。
我的困惑是每次的count
都是新建的数组,每个单词的 特殊值 不同,每个单词都会单独成组。
但事实是:
JS 对象特性
根据 JS 的语言特性,对象的key
只能是字符串或者Symbol
类型。
count
作为数组类型,在被当作对象的key
使用时,会进行隐式数据类型转换,被转换为一个字符串。
于是,只要有一些单词的字母计数一样,那么它们的count
“序列化” 成字符串之后就是相等的。因此,可以被正确地分为一组。
测试
在 Node.js 中测试,使用一个数组作为对象的key
来创建一个键值对,输出对象的keys
发现自动被转换成字符串了。