给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:
输入: nums = [1], k = 1
输出: [1]
说明:
你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。
你的算法的时间复杂度必须优于 O(n log n) , n 是数组的大小。
思路:
1.哈希表建立映射算出key和key出现的次数,用结构体存储。
2.堆结构体建最小堆,然后如果大于堆顶,替换最小堆堆顶,重新排列。
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
class Solution {
public:
struct knode{
int key; //key值
int value; //key出现的次数
};
vector<int> topKFrequent(vector<int>& nums, int k) {
vector<int> keyVec;
for(int i=0;i<nums.size();i++){
int key = nums[i];
if(m_map.count(key)==0){
keyVec.push_back(key);
m_map[key] = 1;
}else{
m_map[key]++;
}
}
/* 前k的数先加入最小堆 */
vector<knode*> minHeapArr;
for(int i=0;i<k;i++){
knode *temp = new knode();
temp->key = keyVec[i];
temp->value = m_map[temp->key];
minHeapArr.push_back(temp);
}
buildminHeap(minHeapArr,minHeapArr.size());
for(int i=k;i<keyVec.size();i++){
int CurKey = keyVec[i];
if(m_map[CurKey]>minHeapArr[0]->value){
minHeapArr[0]->key = CurKey;
minHeapArr[0]->value = m_map[CurKey];
buildminHeap(minHeapArr,minHeapArr.size());
}
}
vector<int>res;
for(int i=0;i<minHeapArr.size();i++){
res.push_back(minHeapArr[i]->key);
}
return res;
}
private:
/* 建立映射 */
unordered_map<int,int> m_map;
void heapsort(vector<knode*> &arr,int start, int end){
int dad = start;
int son = 2*dad+1;
while(son<=end){
if(son+1 <= end && arr[son]->value > arr[son+1]->value){
son++;
}
if(arr[dad]->value < arr[son]->value){
return;
}else{
swap(arr[dad],arr[son]);
dad = son;
son = 2*dad+1;
}
}
}
void buildminHeap(vector<knode*> &arr, int len){
for(int i=len/2-1;i>=0;i--){
heapsort(arr,i,len-1);
}
}
};
int main(){
vector<int> test1= {1,1,1,2,2,3,4,4,4,4,4,4,4};
vector<int> test2={5,-3,9,1,7,7,9,10,2,2,10,10,3,-1,3,7,-9,-1,3,3};
Solution*ps = new Solution();
vector<int>res = ps->topKFrequent(test2,3);
for(int i=0;i<res.size();i++){
cout<<res[i]<<endl;
}
return 0;
}