Leetcode 347. 前 K 个高频元素

该博客讨论了一种C++实现的方法来找到数组中出现频率前k高的元素。通过创建一个结构体数组,存储数值、频率和标志位,先对原始数组进行排序,然后遍历并更新结构体数组的频率。最后,对结构体数组按照频率进行排序,并返回前k个结果。这种方法涉及排序、计数和数组操作。
摘要由CSDN通过智能技术生成

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值