JS找出前K个高频元素

152 阅读2分钟

先发一张自拍,今天的我长这样~!

正题

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]

示例 2:
输入: nums = [1], k = 1
输出: [1]

首先了解一下题意,示例1中 1出现了3次, 2出现了2次 ,3出现了1次,k = 2 ,也就是找出出现次数排名前2的的元素值, 其中 12出现次数为第一和第二,所以输出 [1,2]

那么这样一来,这题的核心就是出现次数的排序,然后取前 K 个 值所对应的数据

在之前的文章中有提到计数排序的解析,是通过下标来排序的一种特殊排序方法,顾名思义,即按照顺序进行计数的一种排序手段,其中就可以求的每个元素出现的次数。

image.png

上图具体详情具体可参考前文章 计数排序的解析

下面以测试用例:

[4,1,-1,2,-1,2,3]
k=2

为例

先实现一个计数:

var topKFrequent = function(nums, k) {
    const min = Math.min(...nums)
    const max = Math.max(...nums)
    let countList = new Array(max - min + 1).fill(0)
    nums.forEach(num => {
        countList[num - min] = countList[num - min] + 1
    })
    console.log({countList})
}

打印结果:

{ countList: [ 2, 0, 1, 2, 1, 1 ] }

这个结果如何去读懂呢?

实际上如果了解过计数排序的应该知道,表示的是

-1 出现过 2次

0 出现过 0次

1 出现过 1次

2 出现过 2次

3 出现过 1次

4 出现过 1次

那么问题来了,得到了这样的数据之后,进行排序,再取前k个元素得到的只能是次数,而并非题目要求的元素的值!(因为 countList 元素表示的是出现次数)

所以在计数的基础上,需要更改数据结构,达到能够找到对应元素值的目的!

修改后:

var topKFrequent = function(nums, k) {
    const min = Math.min(...nums)
    const max = Math.max(...nums)
    let countList = new Array(max - min + 1).fill({val: 0, count: 0})
    nums.forEach(num => {
        countList[num - min] = {
            val : num,
            count: countList[num - min].count + 1
        }
    })
        console.log({countList})
   
};

打印结果

{ countList: [ { val: -1, count: 2 }, { val: 0, count: 0 }, 
{ val: 1, count: 1 }, { val: 2, count: 2 },
{ val: 3, count: 1 }, { val: 4, count: 1 } ] }

这样数据结构就非常的清晰了!接下来就是筛选操作的体力活,就不做过多介绍, show you my code !

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number[]}
 */ // 3 2 5 7. 2-0 3-1 
var topKFrequent = function(nums, k) {
    const min = Math.min(...nums)
    const max = Math.max(...nums)
    let countList = new Array(max - min + 1).fill({val: 0, count: 0})
    nums.forEach(num => {
        countList[num - min] = {
            val : num,
            count: countList[num - min].count + 1
        }
    })
    countList = countList.sort((a,b) => {return b.count - a.count})
    let index = 0
    const res = []
    while(index < k) {
        res.push(countList[index].val)
        index++
    }
    return res
};

image.png