关于leetcode:力扣之按照频率将数组升序排序

56次阅读

共计 2146 个字符,预计需要花费 6 分钟才能阅读完成。

问题形容

给你一个整数数组 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 汇合的应用
  • 二维数组的简略利用
  • 二维数组的排序

正文完
 0