TOP-K问题
目录
问题描述
解法及思想
第一种方式
算法思想
具体实现
第二种方式
算法思想
具体实现
问题描述
Top-K问题是一个十分经典的问题,一般有以下两种方式来描述问题:
- 在10亿的数字里,找出其中最大的100个数;
- 在一个包含n个整数的数组中,找出最大的100个数。
前边两种问题描述稍有区别,但都是说的Top-K问题,前一种描述方式是说这里也许没有足够的空间存储大量的数字或其他东西,我们最好可以在一边输入数据,一边求出结果,而不需要存储数据;后一种说法则表示可以存储数据,这种情况下,最简单直观的想法就是对数组进行排序,取后100个数即为所求。
解法及思想
第一种方式
这种情况下,关键在于不能消耗太大的内存,无法通过数组的简单排序来求取最大的K个数,于是我们应该想到堆排序,求最大的K个数,就采用大小为K的最小二叉堆来实现;我们知道二叉堆可以看作是一颗近似的完全二叉树,其根节点正好就是K个数中最小的一个。
算法思想
先输入K个数,建立一个大小为K的最小二叉堆,接着每输入一个数,与堆的根节点进行比较,如果比根节点还小,说明不可能为最大的K个数之一,如果比根节点大,那么替换根节点的值,接着下沉根节点,维护二叉堆的性质。这样到成功输入所有数据后,最小二叉堆里剩下的就为最大的K个数。(如果求最小的K个数,同理换成最大二叉堆即可)。
时间复杂度由于算法主要涉及对二叉堆结构的操作,所以总体时间复杂度为O(nlgK)。
具体实现
/*
*代码采用STL中的最小优先队列实现,由于STL中自带最小优先队列,其底层就是二叉堆实现,
*所以就不再手写二叉堆了。最小优先队列顶层元素总是队列中最小的元素,也就是二叉堆堆顶。
*/#include <iostream>
#include <queue>
#include <vector>
using namespace std;/*由于STL自带优先队列是默认最大优先的,所以自己写了一个比较函数,将其改为最小优先*/
struct cmp1 {bool operator ()(int &a, int &b) {return a>b; //最小值优先}
};int main() {//这里用来测试,输入格式:先输入需要求的最大K个数中的K值,再依次输入数据流int K = 0;cin >> K;int tmp = 0;int i = 0;priority_queue<int,vector<int>,cmp1> minHeap; //建立最小优先队列while (cin >> tmp) { //循环输入数据流if (i < K) { //先建立一个K个大小的优先队列,也就是K大小的二叉堆minHeap.push(tmp);}else { //算法实现if (tmp <= minHeap.top())continue;else if (tmp > minHeap.top()) {minHeap.pop();minHeap.push(tmp);}}i++;}while (!minHeap.empty()) { //输出最大的K个数cout << minHeap.top() << endl;minHeap.pop();}return 0;
}
第二种方式
这种情况,由于可以操作存储数据的数组,所以我们采用排序的方式进行求解,但一般的排序时间复杂度也挺高,题目只求最大的K个数,不需要完全排序;于是我们想到可以借用快排思想来进行求解。
算法思想
我们知道,每运行一次Partition函数都会确定一个数m的最终位置,且小于m的数均在其左边,大于m的数都在其右边,所以我们的目的就是当数m的右边正好有K-1个数的时候停止算法,得到答案。每次运行Partition函数时,根据前边上述性质,若
- K<右边数组长度,那么要找的K个数一定在m右边,对m右边的数组运行Partition函数;
- K=右边数组长度+1,那么正好找到最大的K个数,为数m以及其右边数组,停止算法;
- 其他情况,最大的K个数不仅仅在m数右边数组中,对m左边数组运行Partition函数。
时间复杂度:与快排类似,Quick Select同样也是不稳定的算法,最坏情况下时间复杂度会达到O(n^2),但平均性能也与快排类似,时间复杂度一般可认为为O(n)。
具体实现
#include <iostream>
#include <vector>using namespace std;void swap(vector<int>&arr, int l, int r)//元素交换函数
{int temp = arr[l];arr[l] = arr[r];arr[r] = temp;
}int Partition(vector<int>&arr, int left, int right)
{int less = left - 1;//选准左边界int more = right;//右边界int temp = arr[right];//选定基准位置while (left < more){if (arr[left] < temp){swap(arr, ++less, left++);//当前元素小于基准元素,左边界内扩}else if (arr[left] > temp)//当前元素大于基准元素,右边界内扩,左边界不变{swap(arr, --more, left);}elseleft++;}swap(arr, more, right);//最后一个基准位置交换return left;//如果存在元素相等情况,返回相同元素两侧的边界索引
}int main() {cout << "请输入K: " << endl;int K = 0; //测试部分,输入需要求的K值大小,然后再依次输入数组元素cin >> K;int tmp = 0;vector<int> vec = {1,2,6,8,10,50,34,36,27,58,70,66};int size = vec.size();if (size == 0 || K > size)return 0;if (size == K){for (int i = 0; i < size; i++) { //测试部分,输出需要求的K个数cout << vec[i] << endl;}}int left = 0;int right = vec.size() - 1;int index = Partition(vec, left, right);while (index != size - K) { //当Partition返回值及右边部分不是K大小时,继续循环int sizeOfRight = size - index - 1; //记录index右边数组长度大小if (K <= sizeOfRight) {index = Partition(vec, index + 1, right);}else if (K == sizeOfRight + 1) //这一步好像有点多余,while循环保证了这点,但为了对应博客文字描述就加上了continue;else if (K > sizeOfRight + 1) {index = Partition(vec, left, index - 1);}}cout << "输出TOPK个元素: " << endl;for (int i = index; i < size; i++) { //测试部分,输出需要求的K个数cout << vec[i] << " ";}cout << endl;return 0;
}
相关文章:
TOP-K问题
目录 问题描述 解法及思想 第一种方式 算法思想 具体实现 第二种方式 算法思想 具体实现 问题描述 Top-K问题是一个十分经典的问题,一般有以下两种方式来描述问题: 在10亿的数字里,找出其中最大的100个数;在一个包含n个整…...
【保姆级从0到1】UE5 蓝图入门教程1:关卡、蓝图入门
20230113 1、新建项目 新建选择 UE 5.1 项目 选择蓝图,项目位置 改变编辑器布局,选择经典布局 2、关卡与蓝图 选择 File -> New Level 准备创建关卡 选择 Basic,点击 Create 进行创建 Ctrl S 保存新建的关卡 关卡蓝图的打开 鼠标右键&…...
【码银送书第六期】《ChatGPT原理与实战:大型语言模型的算法、技术和私有化》
写在前面 2022年11月30日,ChatGPT模型问世后,立刻在全球范围内掀起了轩然大波。无论AI从业者还是非从业者,都在热议ChatGPT极具冲击力的交互体验和惊人的生成内容。这使得广大群众重新认识到人工智能的潜力和价值。对于AI从业者来说…...
redis 报错 Redis protected-mode 配置文件没有真正启动
(error) DENIED Redis is running in protected mode because protected mode is enabled Redis protected-mode 是3.2 之后加入的新特性,在Redis.conf的注释中,我们可以了解到,他的具体作用和启用条件 链接redis 时只能通过本地localhost …...
解决a标签内容中img标签和p标签垂直方向间隔太大的问题
现象如下: 对应的html结构: 解决办法:给a标签设置:display: inline-block和line-height属性。 然后问题解决: 具体原理如下(由chatgpt回答): display: inline-block 可以减少垂直方…...
如何选择靠谱的全景平台?VR全景加盟从哪方面对比?
VR全景行业经过近几年的发展,已经逐渐普及开来,线下各个行业都有实体商家开始引入VR全景去做营销宣传推广了。不少老板也意识到线上线下双渠道的重要性,而VR全景的存在就刚好满足各行各业的需求,从这一点不难看出,VR全…...
CentOS系统环境搭建(十八)——CentOS7安装Docker20.10.12和docker compose v2
centos系统环境搭建专栏🔗点击跳转 CentOS7安装Docker20.10.12和docker compose v2 关于Docker旧版本和docker compose1.0版本的安装可以看这一篇CentOS系统环境搭建(三)——Centos7安装Docker&Docker Compose。 1.卸载旧版本 卸载do…...
NebulaGrap入门介绍和集群安装部署
长风破浪八千里,落日晚霞不回头。 ——大宁。 NebulaGrap——分布式图数据库 官方文档: NebulaGraph Database手册 官方文档 介绍 简介: NebulaGraph 一款开源、分布式图数据库,擅长处理超大规模数据集。 Nebula …...
thinkphp5.0 composer 安装oss提示php版本异常
场景复现: 本地 phpstudy 环境,安装的有7.0到7.3三个版本,首先确认composer已经安装 composer安装阿里云oss的命令为:composer require aliyuncs/oss-sdk-php 运行报错: Problem 1- Root composer.json requires php…...
AList dokcer安装及百度网盘挂载
AList是开源的网盘管理工具。本文介绍如何通过docker安装AList并挂载百度网盘 1、AList安装 1.1、系统安装 通过docker命令进行安装,命令如下: docker run -d --restartalways -v /etc/alist:/opt/alist/data -p 5244:5244 --name"alist" xhofe/alist:…...
whereIn 遇到了最大限制,临时表处理方式
当使用whereIn 遇到了限制,比如whereIn target ID 已经超过了10万级别,但是又没办法join其他库表时,可以使用临时表的方式解决,临时表是以一种会话的方式存在,意味着你断开了mysql 这个临时会话会自动销毁。 为了创建…...
基于SSM的校园快递代取系统设计与实现
末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…...
MySQL事务详细讲解
文章目录 什么是事务:1.事务有哪些特性2.并发事务会引起什么问题3.事务的隔离级别有哪些4.Read View在MVCC中如何工作Read View 有四个重要的字段使用 InnoDB 存储引擎的数据库表,它的聚簇索引记录中都包含下面两个隐藏列: 5.可重复读是怎么工作的6.读提…...
[linux] mmcv-full 安装的时候 Building wheel 卡住
(已解决)FileNotFoundError: [Errno 2] No such file or directory: ‘:/usr/local/cuda-11.8/bin/nvcc‘_鳗小鱼的博客-CSDN博客 安装mmcv一直卡在建车轮_梦想成为大佬的王老八的博客-CSDN博客 pip install -U openmim mim install mmcv...
Python怎么实现更高效的数据结构和算法? - 易智编译EaseEditing
要实现更高效的数据结构和算法,你可以考虑以下几个方面的优化: 选择合适的数据结构: 选择最适合你问题的数据结构至关重要。例如,如果需要频繁插入和删除操作,可能链表比数组更合适。如果需要高效查找操作࿰…...
03-zookeeper节点动态上下线案例
服务器动态上下线监听案例 需求 在分布式系统中,主节点可以有多台,可以动态上下线,任意一台客户端都能实时感知到主节点服务器的上下线。 需求分析 客户端能实时洞察到服务器上下线的变化 基本流程: 1.服务端启动时去注册…...
如何使用TensorFlow完成线性回归
线性回归是一种简单的预测模型,它试图通过线性关系来预测目标变量。在TensorFlow中,我们可以使用tf.GradientTape来跟踪我们的模型参数的梯度,然后用这个信息来优化我们的模型参数。 以下是一个简单的线性回归的例子: pythonimpo…...
@controller和@RestController的区别
//controller和RestController的区别:RestController的返回值就是结果被输出在浏览器 //controller的返回值会到resources的templates下找 返回值".html" 页面 1.controller 简单的来说,当我们的返回值需要跳转大另一个页面时候,我们就会使…...
GeoNet: Unsupervised Learning of Dense Depth, Optical Flow and Camera Pose 论文阅读
论文信息 题目:GeoNet: Unsupervised Learning of Dense Depth, Optical Flow and Camera Pose 作者:Zhichao Yin and Jianping Shi 来源:CVPR 时间:2018 Abstract 我们提出了 GeoNet,这是一种联合无监督学习框架&a…...
蓝桥杯官网填空题(振兴中华)
题目描述 本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。 小明参加了学校的趣味运动会,其中的一个项目是:跳格子。 地上画着一些格子,每个格子里写一个字,如下所示࿱…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...
9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...
人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型
在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重,适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解,并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...
