//小顶堆
class MinHeap{
constructor(){
this.heap=[]
}
//交换节点
swap(i1,i2){
[this.heap[i1],this.heap[i2]]=[this.heap[i2],this.heap[i1]]
}
//父节点下标,i是子节点的下标
getParent(i){
return (i-1)>>1
}
//左节点
getleft(i){
return 2*i+1
}
//右节点
getright(i){
return 2*i+2
}
//添加的时候,加入在最后一个节点,需要上移
//index为最后一个节点的下标
up(index){
//如果加入的是第一个的位置,则不需要上移
if(index===0){
return
}
//获得当前节点的父元素的下标
const p=this.getParent(index)
//如果父节点存在且父节点次数大于当前次数
if(this.heap[p]&&this.heap[p].count>this.heap[index].count){
this.swap(p,index)
this.up(p)
}
}
//如果是删除操作,则需要执行下移
down(index){
//与最小的子节点交换
const l=this.getleft(index)
const r=this.getright(index)
if(
(this.heap[l] && this.heap[l].count < this.heap[index].count)||
(this.heap[r] && this.heap[r].count < this.heap[index].count)){
if(this.heap[r]&&this.heap[r].count<this.heap[l].count){
this.swap(index,r)
this.down(r)
}else{
this.swap(index,l)
this.down(l)
}
}
}
//添加
insert(val){
this.heap.push(val) //加入在堆的最后
this.up(this.heap.length-1)
}
//删除堆顶元素
pop(){
//把最后一个放在第一个
this.heap[0]=this.heap.pop()
this.down(0)
}
//获取堆顶
top(){
return this.heap[0]
}
//获取堆的大小
size(){
return this.heap.length
}
}
var topKFrequent = function(nums, k) {
const map = new Map();
//统计key字符和value次数
for(const num of nums) {
map.set(num, (map.get(num) || 0) + 1);
}
//创建小顶堆
const minh=new MinHeap()
// 遍历map,将{num, count}入堆
// 若堆元素大于k,堆顶弹出
for(const [num,count] of map){
//把map的一个对象作为一个参数
minh.insert({num,count})
if(minh.size()>k){
minh.pop()
}
}
return minh.heap.map(item=>item.num)
};