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 个高频元素的集合是唯一的
思路
看不懂官方的C语言题解,然后代码随想录里面是用c++写的,也不太懂,但是脑子里面有大概一个思路,就是有点麻烦
大概思路就是用一个结构体数组,来存储数值,频率,然后最后又加了一个变量flag来判断这个位置是否放入了数据
将结构体数组初始化为0
要先把nums数组进行升序排序(降序应该也可以的)
然后判断目前的位置是否放入了数字,或者nums当前的数字是否和结构体数组当前的值相等,(flag= =0 || nums[i] = = hh[top].val) 然后 如果flag==0就让flag=1,每次都把cnt++
否则,如果当前nums的数值和当前结构体数组的值不相等的话,就top++,继续进行赋值,顺便把flag = 1
最后把结构体数组按照cnt 的大小进行降序排序
把前k个结果放进malloc的数组里面返回就好了,对了,别忘了把*returnSize改成k
代码
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
struct Hash_table {
int val;
int cnt;
int flag;
}hh[100000];
typedef struct Hash_table hash;
int cmp(const void* a, const void* b) {
hash* p = (hash*)a;
hash* q = (hash*)b;
return -(p->cnt - q->cnt);
}
int cmpp(const void*a, const void*b){
int* p = (int*)a;
int* q = (int*)b;
return *p - *q;
}
int* topKFrequent(int* nums, int numsSize, int k, int* returnSize){
qsort(nums, numsSize, sizeof(int), cmpp);
memset(hh, 0, sizeof(hh));
int top = 0;
for (int i = 0; i < numsSize; i++) {
if (hh[top].flag == 0 || nums[i] == hh[top].val) {
if (hh[top].flag == 0) {
hh[top].flag = 1;
}
hh[top].cnt++;
hh[top].val = nums[i];
}
else {
top++;
hh[top].flag = 1;
hh[top].cnt++;
hh[top].val = nums[i];
}
}
qsort(hh, top+1, sizeof(struct Hash_table), cmp);
int* result = malloc(sizeof(int) * k);
for (int i = 0; i < k; i++) {
result[i] = hh[i].val;
}
*returnSize = k;
return result;
}