[JS] 字母异位词分组与JS中对象键值特性

cnblogs 2024-07-24 08:11:00 阅读 90

本文由leetcode的字符异位词分组题目引入,记录了javascript中对象的键的数据类型以及存在的数据类型转换现象。

题目地址: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] 仅包含小写字母

这道题是一道经典的哈希表应用题,哈希表在这道题里面有两个应用:

  1. 对于一个单词,建立字母到字母出现次数的映射;
  2. 对于题目给定的单词数组,需要建立一个 特殊值 到单词组的映射;

其中的 特殊值 应该满足由单词计算得到,且不同的字母异位词的 特殊值 是相同的。

官方题解

/**

* @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发现自动被转换成字符串了。

image-20240724004023286



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。