⚡️347. 前 K 个高频元素⚡️
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:
输入: nums = [1], k = 1
输出: [1]
提示:
1 <= nums.length <= 105
k 的取值范围是 [1, 数组中不相同的元素的个数]
题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的
进阶:你所设计算法的时间复杂度 必须 优于 O(n log n) ,其中 n 是数组大小。
⚡️分析⚡️
题目要求返回其中出现频率前 k 高的元素,因此可用map结构配合小根堆进行解决。
先用map存储数组中各数字出现的次数,再利用出现的次数,即键值对中的key,进行小根堆排序,当数量大于k个,就将小根堆堆顶元素移除(移除的必定是出现次数最少的),直到符合题意
代码如下:
class MinHeap {
constructor(){
this.heap = [];
}
fatherIndex(index){
return (index-1) >> 1;
}
swap(a,b){
const res = this.heap[a];
this.heap[a] = this.heap[b];
this.heap[b] = res;
}
shiftup(index){
if(index == 0)return;
const father = this.fatherIndex(index);
if(this.heap[father].value > this.heap[index].value){
this.swap(father , index);
this.shiftup(father);
}
}
insert(value){
this.heap.push(value);
this.shiftup(this.heap.length-1);
}
shiftdown(index){
if(index >= this.heap.length)return;
const left = index*2+1;
const right = index*2+2;
if(this.heap[left] && this.heap[index].value > this.heap[left].value){
this.swap(index,left);
this.shiftdown(left);
}
if(this.heap[right] && this.heap[index].value > this.heap[right].value){
this.swap(index,right);
this.shiftdown(right);
}
}
pop(){
this.heap[0] = this.heap.pop();
this.shiftdown(0);
}
Length(){
return this.heap.length;
}
popout(){
return this.heap[0];
}
}
/**
* @param {number[]} nums
* @param {number} k
* @return {number[]}
*/
var topKFrequent = function(nums, k) {
const map = new Map();
nums.forEach(n => {
map.set(n , map.has(n) ? map.get(n) + 1 : 1);
})
const h = new MinHeap();
map.forEach((value,key) => {
h.insert({value,key});
if(h.Length() > k){
h.pop();
}
});
return h.heap.map(n => n.key);
};
算法效率如图:
觉得该篇文章有用的请不要忘记忘记点击右下角的大拇指~
欢迎大家关注我的公众号:Smooth前端成长记录
公众号正在努力更新CSDN博客内容,想方便阅读博客的C友可以来关注我的公众号以便获得更优良的阅读体验~