题目
给你一个整数数组 nums
和一个整数 k
,请你返回其中出现频率前 k
高的元素。你可以按 任意顺序 返回答案。
示例1
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例2
输入: nums = [1], k = 1
输出: [1]
题解
哈希+排序
- 统计数组中每一个元素出现的次数,将数据放在二维数组list中
- 根据每个元素出现的次数排序,对二维数组list排序
- 返回二维数组list前K个数据即可
代码
const topKFrequent = (nums, k) => {
const map = {}
nums.forEach((n) => {
map[n] = (map[n] || 0) + 1
})
const list = []
//遍历数据
Object.keys(map).forEach((k) => {
list.push([Number(k),map[k]])
})
list.sort((a,b)=>{
return b[1] - a[1]
})
const result = list.slice(0,k)
return result.map(v=>v[0])
}
堆排序
在哈希表+排序方法中对所有数据进行排序,这点可以利用堆排序优化,不理解堆的同学可以 点击我,带你了家JavaScript堆
- 统计数组中每一个元素出现的次数,将数据放在二维数组list中
- 将二维数组逐一放入小根堆中
- 小根堆超出k个数据,删除堆顶数据
- 返回小根堆中数据即可得带答案
代码
const topKFrequent = (nums, k) => {
class Heap {
constructor(compare) {
this.list = [0]
this.compare =
typeof compare === 'function' ? compare : this.defaultCompare
}
defaultCompare(a, b) {
return a > b
}
swap(x, y) {
const t = this.list[x]
this.list[x] = this.list[y]
this.list[y] = t
}
isEmpty() {
return this.list.length === 1
}
getSize() {
return this.list.length - 1
}
top() {
return this.list[1]
}
left(x) {
return 2 * x
}
right(x) {
return 2 * x + 1
}
parent(x) {
return Math.floor(x / 2)
}
push(val) {
// 新增数据,向堆尾添加
this.list.push(val)
this.up(this.list.length - 1)
}
// 上浮
up(k) {
const { list, parent, compare } = this
while (k > 1 && compare(list[k], list[parent(k)])) {
this.swap(parent(k), k)
k = parent(k)
}
}
pop() {
const { list } = this
if (list.length === 0) return null
this.swap(1, list.length - 1)
const top = list.pop()
this.down(1)
return top
}
down(k) {
const { list, left, right, compare } = this
const size = this.getSize()
while (left(k) <= size) {
let _left = left(k)
if (right(k) <= size && compare(list[right(k)], list[_left])) {
_left = right(k)
}
if (compare(list[k], list[_left])) return
this.swap(k, _left)
k = _left
}
}
}
const map = {}
nums.forEach((n) => {
map[n] = (map[n] || 0) + 1
})
//小根堆
const heap = new Heap((a, b) => a[1] < b[1])
//遍历数据
Object.keys(map).forEach((key) => {
heap.push([Number(key), map[key]])
if (heap.getSize() > k) {
heap.pop()
}
})
//console.log('heap', heap)
const size = heap.getSize()
const result = []
for (let i = 0; i < size; i++) {
const top = heap.top()
heap.pop()
result.unshift(top[0])
}
return result
}