文章目录

  • 一、题目
    • 1、题目描述
    • 2、基础框架
    • 3、原题链接
  • 二、解题报告
    • 1、思路分析
    • 2、时间复杂度
    • 3、代码详解
  • 三、本题小知识
  • 四、加群须知

一、题目

1、题目描述

  设计一个找到数据流中第 k 大元素的类(class)。注意是排序后的第 k 大元素,不是第 k 个不同的元素。请实现 KthLargest 类:
  1)KthLargest(int k, int[] nums) 使用整数 k 和整数流 nums 初始化对象。
  2)int add(int val) 将 val 插入数据流 nums 后,返回当前数据流中第 k 大的元素。
  样例输入: ["KthLargest", "add", "add", "add", "add", "add"] [[3, [4, 5, 8, 2]], [3], [5], [10], [9], [4]]
  样例输出: [null, 4, 5, 5, 8, 8]

2、基础框架

  • C语言 版本给出的基础框架代码如下:
typedef struct {} KthLargest;KthLargest* kthLargestCreate(int k, int* nums, int numsSize) {}int kthLargestAdd(KthLargest* obj, int val) {}void kthLargestFree(KthLargest* obj) {}

3、原题链接

剑指 Offer II 059. 数据流的第 K 大数值
LeetCode 703. 数据流中的第 K 大元素

二、解题报告

1、思路分析

   维护一个小顶堆,堆的元素始终保持 kkk 个,那么堆顶的就一定是第 kkk 大的元素。

2、时间复杂度

  创建堆的过程为 O(nlog2n)O(nlog_2n)O(nlog2​n),每次执行插入,都要执行弹出操作,单次插入删除的时间复杂度为 O(log2n)O(log_2n)O(log2​n)。

3、代码详解


/**********************************小顶堆模板************************************/
#define lson(idx) (idx << 1|1)
#define rson(idx) ((idx + 1) << 1)
#define parent(idx) ((idx - 1) >> 1)
#define root 0
#define DataType int// -1 和 1 交换,就变成了大顶堆
int compareData(const DataType* a, const DataType* b) {if(*a < *b) {return -1;}else if(*a > *b) {return 1;}return 0;
}void swap(DataType* a, DataType* b) {DataType tmp = *a;*a = *b;*b = tmp;
}typedef struct {DataType *data;int size;int capacity;
}Heap;// 内部接口,小写驼峰// heapShiftDown 这个接口是一个内部接口,所以用小写驼峰区分,用于对堆中元素进行删除的时候的下沉调整;
void heapShiftDown(Heap* heap, int curr) {int son = lson(curr);while(son < heap->size) {if( rson(curr) < heap->size ) {if( compareData( &heap->data[rson(curr)], &heap->data[son] ) < 0 ) {son = rson(curr);                        // 始终选择值更小的结点}        }if( compareData( &heap->data[son], &heap->data[curr] ) < 0 ) {swap(&heap->data[son], &heap->data[curr]);   // 子结点的值小于父结点,则执行交换;curr = son;son = lson(curr);}else {break;                                       // 子结点的值大于父结点,说明已经正确归位,下沉操作结束,跳出循环;}}
}// heapShiftUp 这个接口是一个内部接口,所以用小写驼峰区分,用于对堆中元素进行插入的时候的上浮调整;
void heapShiftUp(Heap* heap, int curr) {int par = parent(curr);while(par >= root) {if( compareData( &heap->data[curr], &heap->data[par] ) < 0 ) {swap(&heap->data[curr], &heap->data[par]);   // 子结点的值小于父结点,则执行交换;curr = par;par = parent(curr);}else {break;                                       // 子结点的值大于父结点,说明已经正确归位,上浮操作结束,跳出循环;}}
}bool heapIsFull(Heap *heap) {return heap->size == heap->capacity;
}// 外部接口,大写驼峰// 堆的判空
bool HeapIsEmpty(Heap *heap) {return heap->size == 0;
}int HeapSize(Heap *heap) {return heap->size;
}// 堆的插入
// 插到最后一个位置,然后不断进行上浮操作
bool HeapPush(Heap* heap, DataType data) {if( heapIsFull(heap) ) {return false;}heap->data[ heap->size++ ] = data;heapShiftUp(heap, heap->size-1);return true;
}// 堆的删除
// 1、删除堆顶元素时,将堆底部的下标最大的元素放入对顶;
// 2、然后调用 shiftDown 将这个元素进行下沉操作;
// 对于小顶堆来说,从根到叶子的路径必然是单调不降的,所以下沉操作一定会终止在路径的某个点,并且保证所有的堆路径还是能够维持单调不降;
bool HeapPop(Heap *heap) {if(HeapIsEmpty(heap)) {return false;}heap->data[root] = heap->data[ --heap->size ];heapShiftDown(heap, root);return true;
}DataType HeapTop(Heap *heap) {assert(!HeapIsEmpty(heap));return heap->data[root];
}// 创建堆
Heap* HeapCreate(DataType *data, int dataSize, int maxSize) {int i;Heap *h = (Heap *)malloc( sizeof(Heap) );h->data = (DataType *)malloc( sizeof(DataType) * maxSize );h->size = 0;h->capacity = maxSize;for(i = 0; i < dataSize; ++i) {HeapPush(h, data[i]);}return h;
}// 销毁堆
void HeapFree(Heap *heap) {free(heap->data);free(heap);
}/**********************************小顶堆模板************************************/typedef struct {Heap *heap;int K;
} KthLargest;KthLargest* kthLargestCreate(int k, int* nums, int numsSize) {KthLargest *KL = (KthLargest *)malloc( sizeof(KthLargest) );KL->K = k;KL->heap = HeapCreate(nums, numsSize, 100000);  // (1)return KL;
}int kthLargestAdd(KthLargest* obj, int val) {HeapPush(obj->heap, val);while(HeapSize(obj->heap) > obj->K) {           // (2)HeapPop(obj->heap);}return HeapTop(obj->heap);
}void kthLargestFree(KthLargest* obj) {HeapFree(obj->heap);free(obj);
}/*** Your KthLargest struct will be instantiated and called as such:* KthLargest* obj = kthLargestCreate(k, nums, numsSize);* int param_1 = kthLargestAdd(obj, val);* kthLargestFree(obj);
*/
  • (1)(1)(1) 创建一个小顶堆;
  • (2)(2)(2) 维持堆元素个数始终为 kkk 个;

三、本题小知识

  堆 可以用于实现 KKK 大数。


四、加群须知

  相信看我文章的大多数都是「 大学生 」,能上大学的都是「 精英 」,那么我们自然要「 精益求精 」,如果你还是「 大一 」,那么太好了,你拥有大把时间,当然你可以选择「 刷剧 」,然而,「 学好算法 」,三年后的你自然「 不能同日而语 」
  那么这里,我整理了「 几十个基础算法 」 的分类,点击开启:

⭐算法入门⭐《堆》中等02 —— LeetCode 703. 数据流中的第 K 大元素相关推荐

  1. Java实现 LeetCode 703 数据流中的第K大元素(先序队列)

    703. 数据流中的第K大元素 设计一个找到数据流中第K大元素的类(class).注意是排序后的第K大元素,不是第K个不同的元素. 你的 KthLargest 类需要一个同时接收整数 k 和整数数组n ...

  2. leetcode 703. 数据流中的第K大元素 最小堆解法 c语言

    如题: 设计一个找到数据流中第K大元素的类(class).注意是排序后的第K大元素,不是第K个不同的元素. 你的 KthLargest 类需要一个同时接收整数 k 和整数数组nums 的构造器,它包含 ...

  3. leetcode 703. 数据流中的第 K 大元素(堆)

    设计一个找到数据流中第 k 大元素的类(class).注意是排序后的第 k 大元素,不是第 k 个不同的元素. 请实现 KthLargest 类: KthLargest(int k, int[] nu ...

  4. LeetCode 703. 数据流中的第K大元素(优先队列)

    1. 题目 设计一个找到数据流中第K大元素的类(class). 注意是排序后的第K大元素,不是第K个不同的元素. 你的 KthLargest 类需要一个同时接收整数 k 和整数数组nums 的构造器, ...

  5. Leetcode 703. 数据流中的第K大元素 解题思路及C++实现

    解题思路: 使用一个最小堆来存储数据,在C++中,对应是#include<queue>头文件中的priority_queue. 程序逻辑:KthLargest类初始化的时候,先根据nums ...

  6. 703. 数据流中的第 K 大元素

    703. 数据流中的第 K 大元素: 题目链接 :[703. 数据流中的第 K 大元素]https://leetcode-cn.com/problems/kth-largest-element-in- ...

  7. 174. 地下城游戏;剑指 Offer 40. 最小的k个数;378. 有序矩阵中第K小的元素;703. 数据流中的第K大元素

    一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格.我们英勇的骑士(K)最初被安置在左上角的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主. 骑士的初始 ...

  8. 从C语言的角度重构数据结构系列(七)-数据结构堆知识求解数据流中的第K大元素

    前言 在这里给自己打个广告,需要的小伙伴请自行订阅. python快速学习实战应用系列课程 https://blog.csdn.net/wenyusuran/category_2239261.html ...

  9. leetcode703. 数据流中的第K大元素(PriorityQueue 最小堆)

    设计一个找到数据流中第K大元素的类(class).注意是排序后的第K大元素,不是第K个不同的元素. 你的 KthLargest 类需要一个同时接收整数 k 和整数数组nums 的构造器,它包含数据流中 ...

最新文章

  1. apache 日志切割
  2. 8086寄存器组织结构
  3. day17 - 动态内存的分配初步理解
  4. 【深度学习】神经网络的Python代码实现
  5. python中的垃圾回收机制_python里面的垃圾回收机制
  6. VC++ 读取和保存文件对话框及默认目录
  7. Java重写equals方法时为什么要重写hashCode方法
  8. 计算机电缆对绞节距,DJYPVP阻燃计算机电缆32/0.2芯数直径
  9. C++新特性探究(13.6):右值引用再探究
  10. jQuery mobile网格布局
  11. 关于 Linux 的配置文件 /etc/profile 路径出错后相关的命令失效解决方式(如:ls,vi不能用)...
  12. 服务机器人占领智能安防哪些领域?
  13. 多线程id为什么是负的?原因
  14. 华为ensp 交换机vlan配置
  15. 推荐系统系列 - 引导 - 5类系统推荐算法,非常好使,非常全
  16. 2、那智机器人时序基板的TBEX1、TBEX2连接
  17. 解决 你的组织策略阻止我们完成此操作
  18. VIVO市场ASO实战详解,vivo应用市场优化
  19. c语言中ipv6地址比较大小,ipv6地址处置
  20. 神经网络预测结果分析,神经网络预测适用范围

热门文章

  1. 搭建个人图床【阿里云OSS+PicGo】
  2. JJJ:配置ubuntu虚拟机网络
  3. Hadoop势微,云原生上位——传统大数据平台的云原生化改造
  4. kube-apiserver准入
  5. 马尔萨斯模型的分析和应用
  6. 推荐一个基于 Vue 的前端界面可视化设计器项目
  7. 大容量充电宝或成乘机“累赘”
  8. 怎样成长为更好的自己--《靠谱:顶尖咨询师教你的工作基本功》
  9. java:对象比较的三种方法equals()方法,Comparator接口,Comparable接口
  10. 基于FPGA的RISC_V五级流水设计---存储设计