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

  • [JS] 字母异位词分组与JS中对象键值特性已关闭评论
  • 47 次浏览
  • A+
所属分类:Web前端
摘要

题目地址:LeetCode 49. 字母异位词分组给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

题目地址: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] = 展开;     }     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] = 展开; 

特殊值 相同的单词分为一组。

我的困惑是每次的count都是新建的数组,每个单词的 特殊值 不同,每个单词都会单独成组。
但事实是

JS 对象特性

根据 JS 的语言特性,对象的key只能是字符串或者Symbol类型。

count作为数组类型,在被当作对象的key使用时,会进行隐式数据类型转换,被转换为一个字符串。

于是,只要有一些单词的字母计数一样,那么它们的count “序列化” 成字符串之后就是相等的。因此,可以被正确地分为一组。


测试

在 Node.js 中测试,使用一个数组作为对象的key来创建一个键值对,输出对象的keys发现自动被转换成字符串了。

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