当前位置: 首页 > news >正文

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问题是一个十分经典的问题&#xff0c;一般有以下两种方式来描述问题&#xff1a; 在10亿的数字里&#xff0c;找出其中最大的100个数&#xff1b;在一个包含n个整…...

【保姆级从0到1】UE5 蓝图入门教程1:关卡、蓝图入门

20230113 1、新建项目 新建选择 UE 5.1 项目 选择蓝图&#xff0c;项目位置 改变编辑器布局&#xff0c;选择经典布局 2、关卡与蓝图 选择 File -> New Level 准备创建关卡 选择 Basic&#xff0c;点击 Create 进行创建 Ctrl S 保存新建的关卡 关卡蓝图的打开 鼠标右键&…...

【码银送书第六期】《ChatGPT原理与实战:大型语言模型的算法、技术和私有化》

写在前面 2022年11月30日&#xff0c;ChatGPT模型问世后&#xff0c;立刻在全球范围内掀起了轩然大波。无论AI从业者还是非从业者&#xff0c;都在热议ChatGPT极具冲击力的交互体验和惊人的生成内容。这使得广大群众重新认识到人工智能的潜力和价值。对于AI从业者来说&#xf…...

redis 报错 Redis protected-mode 配置文件没有真正启动

(error) DENIED Redis is running in protected mode because protected mode is enabled Redis protected-mode 是3.2 之后加入的新特性&#xff0c;在Redis.conf的注释中&#xff0c;我们可以了解到&#xff0c;他的具体作用和启用条件 链接redis 时只能通过本地localhost …...

解决a标签内容中img标签和p标签垂直方向间隔太大的问题

现象如下&#xff1a; 对应的html结构&#xff1a; 解决办法&#xff1a;给a标签设置&#xff1a;display: inline-block和line-height属性。 然后问题解决&#xff1a; 具体原理如下&#xff08;由chatgpt回答&#xff09;&#xff1a; display: inline-block 可以减少垂直方…...

如何选择靠谱的全景平台?VR全景加盟从哪方面对比?

VR全景行业经过近几年的发展&#xff0c;已经逐渐普及开来&#xff0c;线下各个行业都有实体商家开始引入VR全景去做营销宣传推广了。不少老板也意识到线上线下双渠道的重要性&#xff0c;而VR全景的存在就刚好满足各行各业的需求&#xff0c;从这一点不难看出&#xff0c;VR全…...

CentOS系统环境搭建(十八)——CentOS7安装Docker20.10.12和docker compose v2

centos系统环境搭建专栏&#x1f517;点击跳转 CentOS7安装Docker20.10.12和docker compose v2 关于Docker旧版本和docker compose1.0版本的安装可以看这一篇CentOS系统环境搭建&#xff08;三&#xff09;——Centos7安装Docker&Docker Compose。 1.卸载旧版本 卸载do…...

NebulaGrap入门介绍和集群安装部署

长风破浪八千里&#xff0c;落日晚霞不回头。 ——大宁。 NebulaGrap——分布式图数据库 官方文档&#xff1a; ​ NebulaGraph Database手册 ​ 官方文档 介绍 简介&#xff1a; ​ NebulaGraph 一款开源、分布式图数据库&#xff0c;擅长处理超大规模数据集。 Nebula …...

thinkphp5.0 composer 安装oss提示php版本异常

场景复现&#xff1a; 本地 phpstudy 环境&#xff0c;安装的有7.0到7.3三个版本&#xff0c;首先确认composer已经安装 composer安装阿里云oss的命令为&#xff1a;composer require aliyuncs/oss-sdk-php 运行报错&#xff1a; Problem 1- Root composer.json requires php…...

AList dokcer安装及百度网盘挂载

AList是开源的网盘管理工具。本文介绍如何通过docker安装AList并挂载百度网盘 1、AList安装 1.1、系统安装 通过docker命令进行安装&#xff0c;命令如下: docker run -d --restartalways -v /etc/alist:/opt/alist/data -p 5244:5244 --name"alist" xhofe/alist:…...

whereIn 遇到了最大限制,临时表处理方式

当使用whereIn 遇到了限制&#xff0c;比如whereIn target ID 已经超过了10万级别&#xff0c;但是又没办法join其他库表时&#xff0c;可以使用临时表的方式解决&#xff0c;临时表是以一种会话的方式存在&#xff0c;意味着你断开了mysql 这个临时会话会自动销毁。 为了创建…...

基于SSM的校园快递代取系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…...

MySQL事务详细讲解

文章目录 什么是事务:1.事务有哪些特性2.并发事务会引起什么问题3.事务的隔离级别有哪些4.Read View在MVCC中如何工作Read View 有四个重要的字段使用 InnoDB 存储引擎的数据库表&#xff0c;它的聚簇索引记录中都包含下面两个隐藏列&#xff1a; 5.可重复读是怎么工作的6.读提…...

[linux] mmcv-full 安装的时候 Building wheel 卡住

&#xff08;已解决&#xff09;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

要实现更高效的数据结构和算法&#xff0c;你可以考虑以下几个方面的优化&#xff1a; 选择合适的数据结构&#xff1a; 选择最适合你问题的数据结构至关重要。例如&#xff0c;如果需要频繁插入和删除操作&#xff0c;可能链表比数组更合适。如果需要高效查找操作&#xff0…...

03-zookeeper节点动态上下线案例

服务器动态上下线监听案例 需求 在分布式系统中&#xff0c;主节点可以有多台&#xff0c;可以动态上下线&#xff0c;任意一台客户端都能实时感知到主节点服务器的上下线。 需求分析 客户端能实时洞察到服务器上下线的变化 基本流程&#xff1a; ​ 1.服务端启动时去注册…...

如何使用TensorFlow完成线性回归

线性回归是一种简单的预测模型&#xff0c;它试图通过线性关系来预测目标变量。在TensorFlow中&#xff0c;我们可以使用tf.GradientTape来跟踪我们的模型参数的梯度&#xff0c;然后用这个信息来优化我们的模型参数。 以下是一个简单的线性回归的例子&#xff1a; pythonimpo…...

@controller和@RestController的区别

//controller和RestController的区别:RestController的返回值就是结果被输出在浏览器 //controller的返回值会到resources的templates下找 返回值".html" 页面 1.controller 简单的来说&#xff0c;当我们的返回值需要跳转大另一个页面时候&#xff0c;我们就会使…...

GeoNet: Unsupervised Learning of Dense Depth, Optical Flow and Camera Pose 论文阅读

论文信息 题目&#xff1a;GeoNet: Unsupervised Learning of Dense Depth, Optical Flow and Camera Pose 作者&#xff1a;Zhichao Yin and Jianping Shi 来源&#xff1a;CVPR 时间&#xff1a;2018 Abstract 我们提出了 GeoNet&#xff0c;这是一种联合无监督学习框架&a…...

蓝桥杯官网填空题(振兴中华)

题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 小明参加了学校的趣味运动会&#xff0c;其中的一个项目是&#xff1a;跳格子。 地上画着一些格子&#xff0c;每个格子里写一个字&#xff0c;如下所示&#xff1…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...