Leecode刷题C语言之数组大小减半

火影  论坛元老 | 2024-12-16 14:39:29 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1022|帖子 1022|积分 3066

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
执行结果:通过
执行用时和内存消耗如下:
 
 
  1. typedef struct {
  2.     int key;
  3.     int val;
  4.     UT_hash_handle hh;
  5. } HashItem;
  6. HashItem *hashFindItem(HashItem **obj, int key) {
  7.     HashItem *pEntry = NULL;
  8.     HASH_FIND_INT(*obj, &key, pEntry);
  9.     return pEntry;
  10. }
  11. bool hashAddItem(HashItem **obj, int key, int val) {
  12.     if (hashFindItem(obj, key)) {
  13.         return false;
  14.     }
  15.     HashItem *pEntry = (HashItem *)malloc(sizeof(HashItem));
  16.     pEntry->key = key;
  17.     pEntry->val = val;
  18.     HASH_ADD_INT(*obj, key, pEntry);
  19.     return true;
  20. }
  21. bool hashSetItem(HashItem **obj, int key, int val) {
  22.     HashItem *pEntry = hashFindItem(obj, key);
  23.     if (!pEntry) {
  24.         hashAddItem(obj, key, val);
  25.     } else {
  26.         pEntry->val = val;
  27.     }
  28.     return true;
  29. }
  30. int hashGetItem(HashItem **obj, int key, int defaultVal) {
  31.     HashItem *pEntry = hashFindItem(obj, key);
  32.     if (!pEntry) {
  33.         return defaultVal;
  34.     }
  35.     return pEntry->val;
  36. }
  37. void hashFree(HashItem **obj) {
  38.     HashItem *curr = NULL, *tmp = NULL;
  39.     HASH_ITER(hh, *obj, curr, tmp) {
  40.         HASH_DEL(*obj, curr);  
  41.         free(curr);
  42.     }
  43. }
  44. static int compare(const void *a, const void *b) {
  45.     return *(int *)b - *(int *)a;
  46. }
  47. int minSetSize(int* arr, int arrSize) {
  48.     HashItem *freq = NULL;
  49.     for (int i = 0; i < arrSize; i++) {
  50.         hashSetItem(&freq, arr[i], hashGetItem(&freq, arr[i], 0) + 1);
  51.     }
  52.     int occSize = HASH_COUNT(freq);
  53.     int *occ = (int *)calloc(occSize, sizeof(int));
  54.     int pos = 0;
  55.     for (HashItem *pEntry = freq; pEntry; pEntry = pEntry->hh.next) {
  56.         occ[pos++] = pEntry->val;
  57.     }
  58.     qsort(occ, occSize, sizeof(int), compare);
  59.     int cnt = 0, ans = 0;
  60.     for (int i = 0; i < occSize; ++i) {
  61.         cnt += occ[i];
  62.         ans++;
  63.         if (cnt * 2 >= arrSize) {
  64.             break;
  65.         }
  66.     }
  67.     hashFree(&freq);
  68.     return ans;
  69. }
复制代码
解题思绪:
数据结构定义


  • HashItem 结构体

    • 定义一个 HashItem 结构体,包罗三个字段:key(整型,作为哈希表的键),val(整型,存储与键相关联的值),以及 UT_hash_handle hh(由UT-hash库提供,用于内部哈希表管理)。

哈希表操纵函数


  • hashFindItem

    • 接收一个指向哈希表头指针的指针 obj 和一个整型键 key。
    • 在哈希表中查找键为 key 的项,若找到则返回该项的指针,否则返回 NULL。

  • hashAddItem

    • 接收一个指向哈希表头指针的指针 obj、一个整型键 key 和一个整型值 val。
    • 起首检查键 key 是否已存在于哈希表中,若存在则不添加并返回 false。
    • 若不存在,则为新项分配内存,设置其键和值,并将其添加到哈希表中,最后返回 true。

  • hashSetItem

    • 接收一个指向哈希表头指针的指针 obj、一个整型键 key 和一个整型值 val。
    • 在哈希表中查找键为 key 的项,若找到则更新其值为 val。
    • 若未找到,则调用 hashAddItem 函数添加新项。
    • 函数始终返回 true。

  • hashGetItem

    • 接收一个指向哈希表头指针的指针 obj、一个整型键 key 和一个默认整型值 defaultVal。
    • 在哈希表中查找键为 key 的项,若找到则返回其值,否则返回 defaultVal。

  • hashFree

    • 接收一个指向哈希表头指针的指针 obj。
    • 遍历哈希表,删除每个项并释放其内存。

辅助函数


  • compare

    • 用于 qsort 函数举行整型数组的降序排序。

主要函数


  • minSetSize

    • 接收一个整型数组 arr 和其大小 arrSize。
    • 使用哈希表 freq 统计数组中每个元素的出现频率。
    • 遍历哈希表,将每个元素的频率存储到整型数组 occ 中。
    • 对 occ 数组举行降序排序。
    • 初始化计数器 cnt 和答案 ans,遍历排序后的 occ 数组,累加频率到 cnt,同时递增 ans。
    • 当 cnt 的两倍大于或等于数组 arr 的大小时,停止遍历。
    • 释放哈希表 freq 占用的内存。
    • 返回 ans,即所需的最小聚集大小,该聚集中的元素频率之和至少占数组长度的一半。

总结

代码实现了一个基于哈希表的功能,用于统计数组中元素的出现频率,并找到频率之和至少占数组长度一半的最小元素聚集。通过哈希表的快速查找、插入和更新操纵,以及排序算法对频率的排序,代码高效地办理了给定问题。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

火影

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表