怎么修改数组中指定元素_topK问题总结:数组中的前K大元素
起因:2020.11.19 网易互娱面试
面试官:如果有一个战力排行榜,需要实时显示前K名的玩家,你会怎么操作?
我:直接使用最小堆,Java中有priority queue,把它的大小设置为K,每次将数据与它最小的元素(即priorityQueue.peek())比较,比它大就入队,priorityQueue.size()大于k了就弹出peek。这样时间复杂度是
面试官:你能再优化一下吗?
topK问题的一步步优化详解:
给定一个数组nums[],怎样能输出前K大的所有数字呢?
e.g. int[] nums = {8,7,6,5,4,3,2,1}; int k = 3, output: 8, 7, 6
solution 1:直接排序
将nums[]直接进行快排/归并/冒泡等排序,时间复杂度为
简单粗暴,将所有元素排序,但也很明显地增加了工作量,在面试中是很没营养的说法,说了等于没说。
solution 2:局部冒泡
首先厘清一下冒泡排序的逻辑:
public
每次遍历都可以找到一个最大/最小的元素,那么遍历k次就可以找出topK,时间复杂度为
public
solution 3:最小堆/优先队列
什么是最小堆?
堆是一种基本的数据结构,在最小堆中,它的任意一个顶点的值都不大于其子节点。即根节点是该堆中值最小的元素。
最小堆是一棵树,我们很容易得出拥有n个节点的最小堆插入新数据并进行比较的时间复杂度为
我们只需要遍历一次数组。由于最小堆的首节点一定是堆中的最小值,所以如果遍历到的数字大于最小堆的根节点,就弹出首节点,并压入该数字。
Java中的priority queue是一个已经实现的最小堆,很方便,当然手冲堆排序也可以,不过没必要。
直接上代码:
public
其思路与局部冒泡法不同的是,局部冒泡在每次遍历后都能找到一个最大的值,而最小堆法维护了一个“已遍历数据中最大的K个值”的数据结构。
时间复杂度分析非常简单,遍历一次数组是n,由于最小堆的大小是k,所以每次对最小堆操作是logk,所以该算法的时间复杂度为
我们只需要在服务器维护时间建立好我们的小根堆,在游戏服务器开服的时候,如果有玩家氪金导致战斗力变化,我们可以直接将该数据与堆的根节点比较,从而很方便地维护排行榜。
前三种方法都比较好理解,也是基本的方法。
solution 4:分治
此种方法来自于一名知友的回答:
https://zhuanlan.zhihu.com/p/89229902zhuanlan.zhihu.com
其算法的思路大致如下:
在合并数组的时候,维护一个大小为k的空间,内容为该次合并后最大的K个数。
算法过程是很好理解的,但是原作者在回答中说,该算法的时间复杂度为
倘若时间复杂度为
可以肯定的是,该算法的时间复杂度应该是优于直接排序法的,但同时它也带来了额外的空间消耗,因为它至少为每个元素都申请了一个大小为k的数组。
solution 5:线性时间复杂度的搜索算法
思维逐渐深入,既然我要找topK,那我是不是能通过先寻找第K大的数,再用数组里的所有数据与它比较呢?
这种方法是一定可行的,并且它拥有很优秀的时间复杂度。
首先,一句话说明快速排序的逻辑:随机挑选一个pivot,在进行一次算法后,pivot左边的数字都小于它,右边的数字都大于它,换句话说,通过计算最后pivot的下标,就能计算出它是原数组中第几大的数。
怎么修改数组中指定元素_topK问题总结:数组中的前K大元素相关推荐
- python列表元素求和_对Python列表的前k个元素求和?
有两个选项,都使用sum():使用^{}可以有效地提取这些元素:from itertools import islice sum(islice(somelist, k)) 将列表切片,以便只包含以下第 ...
- 数组中的元素赋值给元素_漫画:寻找无序数组的第k大元素
本期封面作者:泰勒太乐 ----- 第二天 ----- 题目是什么意思呢?比如给定的无序数组如下: 如果 k=6,也就是要寻找第6大的元素,这个元素是哪一个呢? 显然,数组中第一大的元素是24,第 ...
- 如何寻找无序数组中的第K大元素?
如何寻找无序数组中的第K大元素? 有这样一个算法题:有一个无序数组,要求找出数组中的第K大元素.比如给定的无序数组如下所示: 如果k=6,也就是要寻找第6大的元素,很显然,数组中第一大元素是24,第二 ...
- 网易_在数组中查找前K个元素
笔试题,最后一题 查找网易云音乐中播放量最大的前K个歌曲. 换句话说,就是在数组中查找前K大元素. 大致有以下几个思路. 1.第一感觉就是对数组进行降序全排序,然后返回前K个元素,即是需要的K个最大数 ...
- 数组中第K大元素(java多种方式实现)
题目描述: Leetcode215题:在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5 ...
- 在一个无序的int数组上构建一个最小堆的时间复杂度_漫画:寻找无序数组的第k大元素(修订版)...
----- 第二天 ----- 题目是什么意思呢?比如给定的无序数组如下: 如果 k=6,也就是要寻找第6大的元素,这个元素是哪一个呢? 显然,数组中第一大的元素是24,第二大的元素是20,第三大的元 ...
- 从当前元素继续寻找_云漫圈 | 寻找无序数组的第k大元素
戳蓝字"CSDN云计算"关注我们哦! 作者:小灰 来源:程序员小灰 本期封面作者:泰勒太乐 ----- 第二天 ----- 题目是什么意思呢?比如给定的无序数组如下: 如果 k ...
- 云漫圈 | 寻找无序数组的第k大元素
戳蓝字"CSDN云计算"关注我们哦! 作者:小灰 来源:程序员小灰 本期封面作者:泰勒太乐 ----- 第二天 ----- 题目是什么意思呢?比如给定的无序数组如下: 如果 k ...
- 遍历数组是什么意思_漫画:寻找无序数组的第k大元素(修订版)
----- 第二天 ----- 题目是什么意思呢?比如给定的无序数组如下: 如果 k=6,也就是要寻找第6大的元素,这个元素是哪一个呢? 显然,数组中第一大的元素是24,第二大的元素是20,第三大的元 ...
- 第k大元素(时间复杂度为O(n))
2201: 第k大元素 [命题人 : yancheng] 时间限制 : 1.000 sec 内存限制 : 128 MB 提交 解决: 156提交量: 1038统计 题目描述 输入一个整数数组,请求出 ...
最新文章
- 数据库1.0 -- 数据库的基本操作
- AlphaCode能替代人类程序员吗?网友:被替代也挺好,这样就可以少写代码多开会了...
- Windows 2003 系统应用故障的分析
- Winform DataGridView列的单元格中动态添加图片和文字
- putty-psftp
- 死磕Java并发:深入分析volatile的实现原理
- python查看文件夹下所有文件
- Java 如何优雅的实现时间控制
- mysql操作日志记录查询_详解mysql数据库参数log_timestamps--控制日志记录使用的时区...
- 会议邀请 | 中国中文信息学会暑期学校《前沿技术讲习班》
- matplotlib库绘图基础
- TypeScript--泛型
- 浅谈导航电子地图的组成和制作流程
- php date 有warning,php提示PHP Warning: date(): It is not safe to rely on the......错误的解决办法...
- c语言实现线程相关操作,如何用C语言实现多线程
- mysql字段加密存储过程_数据库:加密存储过程
- 机顶盒系统升级服务器地址,tvbox
- 清华大学计算机研究生课程表
- 联想拯救者u盘安装linux系统,联想拯救者Y7000系统盘重装如何设置U盘启动
- 计算机禁用打印驱动服务器,设备: 防止用户安装打印机驱动程序