【优选算法】优先级队列 {优先级队列解决TopK问题,利用大小堆维护数据流的中位数}

一、经验总结

优先级队列(堆),常用于在集合中筛选最值或解决TopK问题。

提示:对于固定序列的TopK问题,最优解决方案是快速选择算法,时间复杂度为O(N)比堆算法O(NlogK)更优;而对于动态维护数据流中的TopK,最优解决方案是堆算法,每次添加数据后筛选,时间复杂度为O(logK)比快速选择算法O(N)更优;

优先级队列如何解决TopK问题?

  1. 创建一个大小为K的堆
  2. 循环
    1. 将数组中的元素依次进堆
    2. 判断堆中的元素个数是否大于K,如果大于K就pop弹出堆顶元素
  3. 将数组中的所有元素全部筛选一遍后,堆中剩余的K个元素就是最大(小)的K个元素

TopK问题选用大根堆还是小根堆?

  • 如果要选出最大的K个数,就选用小根堆;
  • 如果要选出最小的K个数,就选用大根堆;

利用大小堆维护数据流中的中位数

  1. 创建一个大堆left用于存储数据流的前一半(升序),一个小堆right用于存储后一半
  2. 控制left的元素个数m和right的元素个数n满足:m==n或m==n+1
  3. 数据流的中位数:当m==n时,mid=(left.top()+right.top())/2;当m==n+1时,mid=left.top();
  4. 新增元素:将新元素与left.top()(或right.top())比较,决定加入left还是right。完成插入后,记得调整两个堆的元素个数使其满足规则。

二、相关编程题

2.1 最后一块石头的重量

题目链接

1046. 最后一块石头的重量 - 力扣(LeetCode)

题目描述

在这里插入图片描述

算法原理

利用堆结构筛选最大值

编写代码

class Solution {
public:int lastStoneWeight(vector<int>& stones) {priority_queue<int> heap;for(auto e : stones) heap.push(e);while(heap.size() >= 2){int s1 = heap.top();heap.pop();int s2 = heap.top();heap.pop();if(s1 > s2) heap.push(s1-s2);}if(heap.size() == 0) return 0;else return heap.top();}
};

2.2 数据流中的第 K 大元素

题目链接

703. 数据流中的第 K 大元素 - 力扣(LeetCode)

题目描述

在这里插入图片描述

算法原理

在这里插入图片描述
这道题更适合使用堆解决,因为add函数插入一个数字后返回当前数据中的第K大的元素,如果使用快速选则算法,复杂度为O(N);而使用堆算法,复杂度为O(logK)

编写代码

class KthLargest {priority_queue<int, vector<int>, greater<int>> _heap;int _k;
public:KthLargest(int k, vector<int>& nums) {_k = k;for(auto e : nums) add(e);}int add(int val) {_heap.push(val);if(_heap.size() > _k)_heap.pop();return _heap.top();}
};

2.3 前K个高频单词

题目链接

692. 前K个高频单词 - 力扣(LeetCode)

题目描述

在这里插入图片描述

算法原理

在这里插入图片描述

编写代码

class Solution {typedef pair<string, int> PSI;struct Cmp{bool operator()(const PSI &left, const PSI &right){if(left.second != right.second) //出现频次不同,选出高频单词,按照小根堆的方式排列return left.second > right.second;elsereturn left.first < right.first; //出现频次相同,按字典序排序,按照大根堆的方式排列}};
public:vector<string> topKFrequent(vector<string>& words, int k) {unordered_map<string, int> hash;priority_queue<PSI, vector<PSI>, Cmp> heap;vector<string> ret(k);//统计所有单词的出现频次for(auto &str:words){++hash[str];} //用一个大小为k的堆筛选TopKfor(auto &psi:hash){heap.push(psi);if(heap.size() > k)heap.pop();}//将结果倒着放入数组for(int i = k-1; i >= 0; --i){ret[i] = heap.top().first;heap.pop();}return ret;}
};

2.4 数据流的中位数

题目链接

295. 数据流的中位数 - 力扣(LeetCode)

题目描述

在这里插入图片描述

算法原理

在这里插入图片描述

编写代码

class MedianFinder {priority_queue<int> left; //大根堆priority_queue<int, vector<int>, greater<int>> right; //小根堆
public:MedianFinder() {}void addNum(int num) {if(left.size() > right.size()) //m > n{int x = left.top();if(num <= x){left.push(num);left.pop();right.push(x);}else{right.push(num);}}else //m == n{int y = right.empty()? 0:right.top();if(right.empty() || num < y){left.push(num);}else{right.push(num);right.pop();left.push(y);}}}double findMedian() {if(left.size() > right.size()) //m > nreturn (double)left.top();else //m == nreturn (left.top()+right.top())/2.0;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/25696.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Matplotlib进行Python绘图

Matplotlib是Python中广泛使用的2D绘图库&#xff0c;适合于各种数据可视化需求。它提供了多种图表类型&#xff0c;如折线图、散点图、柱状图和饼图&#xff0c;帮助用户直观地展示数据。 基本介绍 Matplotlib通过其主要模块pyplot&#xff0c;允许用户用简洁的代码快速绘制…

linux 网桥学习

前言&#xff1a; 本文来学习一下linux网桥概念和网桥配置 1. linux网桥概念 网桥&#xff0c;类似于中继器&#xff0c;连接局域网中两个或者多个网段。它与中继器的不同之处就在于它能够解析它收发的数据&#xff0c;读取目标地址信息&#xff08;MAC&#xff09;&#xff…

立创EDA专业版设置位号居中并调整字体大小

选择某一个器件位号&#xff0c;右键->查找&#xff1a; 选择查找全部&#xff1a; 下面会显示查找结果&#xff1a; 查看&#xff0c;所有的位号都被选中了&#xff1a; 然后布局->属性位置&#xff1a; 属性位置选择中间&#xff1a; 然后位号就居中了 调整字体大小&a…

微信小程序学习笔记(1)

文章目录 一、文件作用app.json&#xff1a;project.config.json:sitemap.json页面中.json 二、项目首页三、语法**WXML**和**HTML**WXSS 和CSS的区别小程序中.js文件的分类 一、文件作用 app.json&#xff1a; 当前小程序的全局配置&#xff0c;包括所有页面路径、窗口外观、…

文件的基础必备知识(初学者入门)

1. 为什么使用文件 2. 什么是文件 3. 二进制文件和文本文件 4. 文件的打开和关闭 1.为什么使用文件 我们写的程序数据是存储在电脑内存中&#xff0c;如果程序退出&#xff0c;内存回收&#xff0c;数据就丢失&#xff0c;等程序再次运行时&#xff0c;上次的数据已经消失。面…

每日复盘-20240607

今日关注&#xff1a; 这几天市场环境不好&#xff0c;一直空仓。 六日涨幅最大: ------1--------605258--------- 协和电子 五日涨幅最大: ------1--------605258--------- 协和电子 四日涨幅最大: ------1--------605258--------- 协和电子 三日涨幅最大: ------1--------0…

入侵报警系统的智慧核心——ARMxy工控机深度应用

智能安防领域高清视频监控、人脸识别门禁系统以及入侵报警系统的智能化升级&#xff0c;正以前所未有的速度推动着行业的变革。在这场变革中&#xff0c;ARMxy工业计算机以其卓越的性能、高度的灵活性及强大的集成能力&#xff0c;成为了众多安防解决方案中的核心组件。 高清视…

线程+线程池+锁

有合适延时代码会补充 线程 创建方式 1&#xff1a;继承Thread 2&#xff1a;实现Runnable接口 3&#xff1a;CallableFuture接口 方法介绍 sleep&#xff1a;Thread类静态方法 当前线程暂停执行指定时间&#xff0c;让出cpu&#xff0c;不释放对象锁&#xff0c;任何地方使用…

BC11 学生基本信息输入输出

BC11 学生基本信息输入输出 废话不多说上题目&#xff1a; 这道题表面上很简单&#xff0c;但是里面有很重要的点先给大家上正确的代码&#xff1a; #include<stdio.h> int main() {int stu 0;float c 0;float English 0;float math 0;scanf("%d;%f,%f,%f"…

3 数据类型、运算符与表达式-3.1 C语言的数据类型和3.2 常量与变量

数据类型 基本类型 整型字符型实型(浮点型) 单精度型双精度型 枚举类型 构造类型 数组类型结构体类型共用体类型 指针类型空类型 #include <stdio.h> #include <string.h> #include <stdbool.h> // 包含布尔类型定义 // 常量和符号常量 #define PRICE 30//…

AI大模型日报#0610:港大等1bit大模型“解决AI能源需求”、谷歌开源TimesFM时序预测模型

导读&#xff1a;AI大模型日报&#xff0c;爬虫LLM自动生成&#xff0c;一文览尽每日AI大模型要点资讯&#xff01;目前采用“文心一言”&#xff08;ERNIE 4.0&#xff09;、“零一万物”&#xff08;Yi-Large&#xff09;生成了今日要点以及每条资讯的摘要。欢迎阅读&#xf…

Jmeter分布式、测试报告、并发数计算、插件添加方式、常用图表

Jmeter分布式 应用场景 当单个测试机无法模拟用户要求的业务场景时&#xff0c;可以使用多台测试机进行模拟&#xff0c;就是Jmeter的分布 式测试。 Jmeter分布式执行原理 Jmeter分布测试时&#xff0c;选择其中一台作为控制机&#xff08;Controller&#xff09;&#xff0c…

Spring5

文章目录 1. Spring 是什么&#xff1f;2. IoC3. Spring Demo4. IoC 创建对象的方式 / DI 方式注入的默认参数在哪里设定? 5. Spring 配置tx:annotation-driven 用于启用基于注解的事务管理 6. Bean的作用域7. 在Spring中有三种自动装配的方式1. 在xml中显式的配置2. 在java中…

RAG:如何从0到1搭建一个RAG应用

通过本文你可以了解到&#xff1a; 什么是RAG&#xff1f;如何搭建一个RAG应用&#xff1f;目前开源的RAG应用有哪些&#xff1f; 大模型学习参考&#xff1a; 1.大模型学习资料整理&#xff1a;大模型学习资料整理&#xff1a;如何从0到1学习大模型&#xff0c;搭建个人或企业…

定个小目标之刷LeetCode热题(15)

这道题直接就采用两数相加的规则&#xff0c;维护一个进阶值&#xff08;n&#xff09;即可&#xff0c;代码如下 class Solution {public ListNode addTwoNumbers(ListNode l1, ListNode l2) {// 新建一个值为0的头结点ListNode newHead new ListNode(0);// 创建几个指针用于…

JAVA基础【String类】

在 Java 编程中&#xff0c;String 类是一个非常重要且常用的类&#xff0c;用于表示字符串对象。本文将详细介绍 Java 中的 String 类&#xff0c;包括定义、常用方法、不可变性特性以及字符串拼接等方面的内容。 1. String 类的定义与创建 定义 String 是 Java 中的一个类…

【C++初阶学习】第十三弹——优先级队列及容器适配器

C语言栈&#xff1a;数据结构——栈(C语言版)-CSDN博客 C语言队列&#xff1a;数据结构——队列&#xff08;C语言版&#xff09;-CSDN博客 C栈与队列&#xff1a;【C初阶学习】第十二弹——stack和queue的介绍和使用-CSDN博客 前言&#xff1a; 在前面&#xff0c;我们已经…

Android基础-自定义view

在Android开发中&#xff0c;自定义View是一个常见的需求&#xff0c;它允许开发者根据应用的具体需求创建独特的UI元素。自定义View可以极大地增强应用的用户界面和用户体验。下面将详细阐述Android中自定义View的方式和方法&#xff0c;包括基本的步骤、常见的技巧和一些深入…

2024.6.10 一

Python多进程 进程 一系列有序指令集用来实现某些功能,每个进程都有自己独立的一块内存空间&#xff0c;一个进程可以有多个线程. 程序就是我们安装好的应用,我们打开程序时,就创建了相应的进程,操作系统会为进程分配相应的资源 线程 是进程中的一个执行任务&#xff08;控制…

Java24:会话管理 过滤器 监听器

一 会话管理 1.cookie 是一种客户端会话技术&#xff0c;cookie由服务端产生&#xff0c;它是服务器存放在浏览器的一小份数据&#xff0c;浏览器 以后每次访问服务器的时候都会将这小份的数据带到服务器去。 //创建cookie对象 Cookie cookie1new Cookie("…