Leecode刷题C语言之超过阈值的最小操作数②

打印 上一主题 下一主题

主题 1007|帖子 1007|积分 3025

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

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

x
实行结果:通过
实行用时和内存消耗如下:
 

 
 
  1. // 最小堆的节点结构体
  2. typedef struct {
  3.     long long* heap;
  4.     int size;
  5.     int capacity;
  6. } MinHeap;
  7. // 初始化最小堆
  8. MinHeap* createMinHeap(int capacity) {
  9.     MinHeap* minHeap = (MinHeap*)malloc(sizeof(MinHeap));
  10.     minHeap->size = 0;
  11.     minHeap->capacity = capacity;
  12.     minHeap->heap = (long long*)malloc(capacity * sizeof(long long));
  13.     return minHeap;
  14. }
  15. // 插入元素到最小堆
  16. void insert(MinHeap* minHeap, long long value) {
  17.     if (minHeap->size == minHeap->capacity) {
  18.         return; // 堆已满
  19.     }
  20.     int i = minHeap->size++;
  21.     while (i != 0 && value < minHeap->heap[(i - 1) / 2]) {
  22.         minHeap->heap[i] = minHeap->heap[(i - 1) / 2];
  23.         i = (i - 1) / 2;
  24.     }
  25.     minHeap->heap[i] = value;
  26. }
  27. // 移除并返回最小堆的最小元素
  28. long long extractMin(MinHeap* minHeap) {
  29.     if (minHeap->size <= 0) {
  30.         return -1;
  31.     }
  32.     if (minHeap->size == 1) {
  33.         minHeap->size--;
  34.         return minHeap->heap[0];
  35.     }
  36.     long long root = minHeap->heap[0];
  37.     minHeap->heap[0] = minHeap->heap[--minHeap->size];
  38.     int i = 0;
  39.     while (2 * i + 1 < minHeap->size) {
  40.         int leftChild = 2 * i + 1;
  41.         int rightChild = 2 * i + 2;
  42.         int smallest = i;
  43.         if (leftChild < minHeap->size && minHeap->heap[leftChild] < minHeap->heap[smallest]) {
  44.             smallest = leftChild;
  45.         }
  46.         if (rightChild < minHeap->size && minHeap->heap[rightChild] < minHeap->heap[smallest]) {
  47.             smallest = rightChild;
  48.         }
  49.         if (smallest != i) {
  50.             long long temp = minHeap->heap[smallest];
  51.             minHeap->heap[smallest] = minHeap->heap[i];
  52.             minHeap->heap[i] = temp;
  53.             i = smallest;
  54.         } else {
  55.             break;
  56.         }
  57.     }
  58.     return root;
  59. }
  60. // 释放最小堆内存
  61. void freeMinHeap(MinHeap* minHeap) {
  62.     free(minHeap->heap);
  63.     free(minHeap);
  64. }
  65. int minOperations(int* nums, int numsSize, int k) {
  66.     MinHeap* minHeap = createMinHeap(numsSize);
  67.     for (int i = 0; i < numsSize; ++i) {
  68.         insert(minHeap, nums[i]);
  69.     }
  70.     int operations = 0;
  71.     while (minHeap->size >= 2 && minHeap->heap[0] < k) {
  72.         long long x = extractMin(minHeap);
  73.         long long y = extractMin(minHeap);
  74.         long long newValue = x * 2 + y;
  75.         insert(minHeap, newValue);
  76.         ++operations;
  77.     }
  78.     freeMinHeap(minHeap);
  79.     return operations;
  80. }
复制代码
解题思绪:
这段代码实现了一个最小堆数据结构,并使用它来办理一个特定的题目:给定一个整数数组 nums 和一个整数 k,计算将数组中的元素通过一系列操作转换成大于或等于 k 的最小元素所需的最少操作次数。每次操作可以取出堆中的两个最小元素,将它们相加后乘以2,再将结果放回堆中。
下面是代码的解题思绪:

  • 定义最小堆结构体

    • MinHeap 结构体包含三个成员:指向堆数组的指针 heap,堆的当前巨细 size,以及堆的容量 capacity。

  • 初始化最小堆

    • createMinHeap 函数分配内存并初始化一个最小堆,设置堆的巨细为0,并分配充足的空间来存储指定容量的元素。

  • 插入元素到最小堆

    • insert 函数将一个新元素添加到最小堆中。如果堆未满,它起首将元素添加到堆的末尾,然后通过上滤(bubble up)操作将其移动到精确的位置,以保持堆的性子。

  • 移除并返回最小元素

    • extractMin 函数移除并返回堆中的最小元素(根元素)。它起首将根元素更换为堆中的末了一个元素,然后通过下滤(bubble down)操作将新的根元素移动到精确的位置。

  • 开释最小堆内存

    • freeMinHeap 函数开释最小堆所占用的内存。

  • 计算最少操作次数

    • minOperations 函数是办理题目的核心。它起首创建一个最小堆,并将数组 nums 中的所有元素插入堆中。
    • 然后,它进入一个循环,只要堆的巨细至少为2且堆顶元素(最小元素)小于 k,就实行以下操作:

      • 从堆中取出两个最小元素 x 和 y。
      • 计算新值 newValue = x * 2 + y。
      • 将 newValue 插入堆中。
      • 操作次数 operations 加1。

    • 循环竣事后,开释堆的内存,并返回操作次数 operations。

这种方法使用了最小堆的性子,确保了每次操作都能有用地处理当前最小的元素,从而以尽可能少的操作次数到达目标值 k。

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

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

刘俊凯

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