问题描述
给你一个整数数组 nums
,请你将数组按照每个值的频率 升序 排序。如果有多个值的频率相同,请你按照数值本身将它们 降序 排序。
请你返回排序后的数组。
示例 1:
输入:nums = [1,1,2,2,2,3]
输出:[3,1,1,2,2,2]
解释:'3' 频率为 1,'1' 频率为 2,'2' 频率为 3 。
示例 2:
输入:nums = [2,3,1,3,2]
输出:[1,3,3,2,2]
解释:'2' 和 '3' 频率都为 2 ,所以它们之间按照数值本身降序排序。
示例 3:
输入:nums = [-1,1,-6,4,5,-6,1,4,1]
输出:[5,-1,4,4,-6,-6,1,1,1]
力扣原题目地址:https://leetcode.cn/problems/...
知识点回顾之Map集合和二维数组
我们知道Map集合可以用于存储一组组键值对数据。比如我们要创建一个Map集合,集合中有三组数据,分别对应为姓名和年龄。
原始数据如下:
姓名 年龄
孙悟空 500
猪八戒 88
沙和尚 1000
创建出来的Map集合如下图
接下来回顾一下创建这个Map集合的两种方式
使用Map.set()方法创建Map集合
一般情况下,我们都是使用Map的set方法去创建自己想要的集合,如下代码:
let map1 = new Map()
map1.set('孙悟空', 500)
map1.set('猪八戒', 88)
map1.set('沙和尚', 1000)
console.log('map1', map1);
使用二维数组创建Map集合
既然Map集合可以存储一组组键值对的数据,那么我们可以把这个一组组数据,当成一个个只包含两个项(第0项是键key、第二项是值value)的数组,然后把整个集合当成一个大数组。
于是一个二维数组就应运而生了。所以在构造函数的协同下,我们可以在实例化Map对象的时候,传入一个二维数组,便是可以达到同样的效果,如下代码:
let map2 = new Map(
[
['孙悟空', 500],
['猪八戒', 88],
['沙和尚', 1000],
]
)
console.log('map2', map2);
由上述两个案例,可以知道Map集合,好像就是二维数组的一种变形方式,一种特殊的二维数组,当然实际不是哦。
- 上方案例使用二维数组创建Map集合可理解为,把二维数组转成对应Map集合;
- 同样的,
Map集合也可转为二维数组,使用Array.from(map)即可
注意,上述二维数组转Map集合案例,是固定项个数。如 内层数组只有两项key项、value项。如果再多几项,会忽略后续的项。因为Map集合的一组数据只有key和value。如下代码
let map = new Map(
[
['孙悟空', 500, '花果山水帘洞'],
['猪八戒', 88, '高老庄'],
['沙和尚', 1000, '通天河'],
]
)
console.log('map', map);
打印出来的结果如下:
{'孙悟空' => 500, '猪八戒' => 88, '沙和尚' => 1000}
就会忽略二维数组中内层数组的第3项 ‘花果山水帘洞、高老庄、通天河’,因为Map集合每一项只能存储两项,键值对
为什么要提到二维数组呢?因为题目需要
解题思路分析
第一步,使用Map集合统计数组中每一项出现的次数(频率)
第二步,因为要把数组做升序排序,所以需要将Map集合转化成二维数组,并调用Array.sort()方法给二维数组做排序
然后再创建一个空数组,双层遍历二维数组,将对应项,追加到空数组中去,并返回即可
解题代码
就以下方定义的nums数组做用例进行理解吧
let nums = [1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 4, 3]
var frequencySort = function (nums) {
// 第一步,使用Map集合统计各项出现的次数
let map = new Map()
for (let i = 0; i < nums.length; i++) {
if (map.has(nums[i])) {
let count = map.get(nums[i])
count = count + 1
map.set(nums[i], count)
} else {
map.set(nums[i], 1)
}
}
// 第二步,将统计好频率次数的Map集合转成二维数组并相应排序
let mmap = Array.from(map) // 注意这里要排序两次
mmap.sort((a, b) => {
return b[0] - a[0] // 第一次排序,按照自身从大到小
})
mmap.sort((a, b) => {
return a[1] - b[1] // 第二次排序,按照出现的频率从小到大
})
// 第三步,定义空数组,并循环二维数组追加即可
let result = []
mmap.forEach((item) => {
for (let j = 0; j < item[1]; j++) { // 注意j小于item[1],item[1]即为出现的次数
result.push(item[0]) // item[0] 指的是原始数组中的每一项;item[0]、item[1] 即为 谁、出现了几次
}
})
return result
};
console.log('结果', frequencySort(nums)); // [4, 3, 9, 9, 9, 9, 1, 1, 1, 1, 1, 1]
总结
题目考查主要是:
- Map集合的使用
- 二维数组的简单应用
- 二维数组的排序
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。