【LeetCode力扣】面试题 17.14. 最小K个数(top-k问题)

目录

1、题目介绍

2、解题思路

2.1、优先队列解法

2.2、top-k问题解法


1、题目介绍

原题链接:面试题 17.14. 最小K个数 - 力扣(LeetCode)

 题目要求非常简短,也非常简单,就是求一组数中的k个最小数。

2、解题思路

        如果在正常刷题过程中遇到这种题,那么这道题毋庸置疑是秒杀题,使用最简单的冒泡排序亦或者是直接使用Java中Arrays类的方法sort直接排序后,再取出前k个值。

        但是,这是一道面试题,面试题的精髓就是要尽可能的压缩时间复杂度空间复杂度,以达到给面试官眼前一亮的效果。显然直接使用自带的排序很难给面试官眼前一亮的效果,而该题有一种统称叫:top-k问题,使用top-k问题经典的解法可以将时间复杂度控制在O(N*logK),空间复杂度O(K)。

下面将使用两种方法来解题,一种是正常解法,一种是top-k问题解法。

2.1、优先队列解法

直接使用优先队列将数组arr中的所有元素入队,最终队中的队头便是最小值,只需要依次出队并存入到返回数组ret中即可。

【完整代码】

class Solution {public int[] smallestK(int[] arr, int k) {int[] ret = new int[k];if(k == 0) {return ret;}Queue<Integer> queue = new PriorityQueue<>();   //优先队列,默认小根堆for(int i = 0 ; i < arr.length; i++) {   //依次入队queue.offer(arr[i]);}for(int i = 0; i < k; i++) {   //依次出队并存入ret[i] = queue.poll();}return ret;}
}

但是显然这样的解法非常的普遍,并不能让面试官眼前一亮,下面带大家认识一下另一个解法,也就是top-k问题的解法。

2.2、top-k问题解法

        top-k问题:即求数据集合中前K个最大的元素或者最小的元素,一般情况下数据量都比较大。比如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。 

        对于top-k问题,能想到的最简单直接的方式就是排序,但是:如果数据量非常大,排序就不太可取了(可能数据都不能一下子全部加载到内存中)。最佳的方式就是用堆来解决,基本思路如下:

1. 用数据集合中前K个元素来建堆

  • 前k个最大的元素,则建小堆
  • 前k个最小的元素,则建大堆

2. 用剩余的N-K个元素依次与堆顶元素来比较,不满足则替换堆顶元素

将剩余N-K个元素依次与堆顶元素比完之后,堆中剩余的K个元素就是所求的前K个最小或者最大的元素。

【思路讲解】

以题目示例为例:

首先用前k个元素建大根堆

用剩余的N-K个元素依次与堆顶元素来比较,如果此时小于堆顶(即队头)则替换堆顶元素。

这样做的原理非常简单:因为此时是大根堆,队头元素即为堆中最大值,如果此时堆外元素还有比堆顶元素小的,那么证明堆顶元素肯定不属于k个最小元素中的一个,此时需要将堆顶(即队头)出队,然后将该元素入队,并重新调整成大根堆。

此时从上图可发现,2小于堆顶(即队头)7,因此需要将7出队,2入队,并调整堆。

 此时从上图可发现,4小于堆顶(即队头)5,因此需要将5出队,4入队,并调整堆。

而后面的6,8都不小于堆顶4,因此堆没有变化,最后得到的大根堆内的所有元素即题目所求的元素,只需要将堆内元素依次出队即可。

【完整代码】

class Solution {public int[] smallestK(int[] arr, int k) {int[] ret = new int[k];if(k == 0) {return ret;}Queue<Integer> queue = new PriorityQueue<>(new ComparaBig()); for(int i = 0; i < k; i++) {   //用前k个元素建大根堆queue.offer(arr[i]);}for(int i = k; i < arr.length; i++) {   //堆顶元素与后续的n-k个元素依次比较if(queue.peek() > arr[i]) {    //当发现当前元素小于堆顶元素时,出队堆顶元素,入队当前元素queue.poll();queue.offer(arr[i]);}}for(int i = 0; i < k; i++) {   //将堆中所有元素出队,依次放到返回数组ret中ret[i] = queue.poll();}return ret;}
}//Java自带的优先队列为小根堆,该题需要使用大根堆,因此需要重写比较器
class ComparaBig implements Comparator<Integer> {  @Overridepublic int compare(Integer o1, Integer o2) {return o2 - o1;}
}
  • 时间复杂度:O(nlogk),其中 n 是数组 arr 的长度。由于大根堆实时维护前 k 小值,所以插入删除都是 O(logk) 的时间复杂度,最坏情况下数组里 n 个数都会插入,所以一共需要 O(nlogk) 的时间复杂度。
  • 空间复杂度:O(k),因为大根堆里最多 k 个数。

更多【LeetCode刷题】推荐:

【LeetCode力扣】42. 接雨水-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/zzzzzhxxx/article/details/134104222?spm=1001.2014.3001.5501【LeetCode力扣】189 53 轮转数组 | 最大子数组和-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/zzzzzhxxx/article/details/134095703?spm=1001.2014.3001.5501【LeetCode力扣】234 快慢指针 | 反转链表 | 还原链表_力扣234-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/zzzzzhxxx/article/details/133958602?spm=1001.2014.3001.5501

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

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

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

相关文章

数据结构:完全二叉树(递归实现)

如果完全二叉树的深度为h&#xff0c;那么除了第h层外&#xff0c;其他层的节点个数都是满的&#xff0c;第h层的节点都靠左排列。 完全二叉树的编号方法是从上到下&#xff0c;从左到右&#xff0c;根节点为1号节点&#xff0c;设完全二叉树的节点数为sum&#xff0c;某节点编…

【重点问题】攻击面发现及管理

Q1&#xff1a;在使用长亭云图极速版时&#xff0c;是否需要增设白名单扫描节点&#xff1f; 长亭云图极速版高级网络安全产品基于一种理念&#xff0c;即攻击面发现是一个不断变换且需要持续对抗的过程。在理想的情况下&#xff0c;用户应当在所有预置防护设施发挥作用的环境…

C++面试:stl的栈和队列介绍

目录 栈 栈&#xff08;stack&#xff09;的声明&#xff1a; push()&#xff1a; 将元素推入栈顶 pop()&#xff1a; 弹出栈顶元素 top()&#xff1a; 访问栈顶元素&#xff0c;但不弹出 empty()&#xff1a; 检查栈是否为空 size()&#xff1a; 返回栈中元素的数量 …

【MQ01】什么是消息队列?用哪个消息队列?

什么是消息队列&#xff1f;用哪个消息队列&#xff1f; 来了来了&#xff0c;消息队列系列总算来咯。对于搜索引擎相关的知识大家消化的怎么样呀&#xff1f;其实对于搜索引擎来说&#xff0c;我们学习的内容还是挺全面的&#xff0c;也算是比较深入了。而对于消息队列来说&am…

6.第一个Python爬虫程序

使用 Python 内置的 urllib 库获取网页的 html 信息。注意&#xff0c;urllib 库属于 Python 的标准库模块&#xff0c;无须单独安装&#xff0c;它是 Python 爬虫的常用模块 获取网页html信息 1) 获取响应对象 向百度&#xff08;百度一下&#xff0c;你就知道&#xff09;…

uniapp使用uni-forms表单校验无效

查看是否写了name属性&#xff0c;且name属性的属性值得和下面v-model绑定的一致&#xff0c;否则校验不生效 官网

一种解决常用存储设备无法被电脑识别的方法

一、通用串行总线控制器描述 通用串行总线&#xff08;Universal Serial Bus&#xff0c;简称USB&#xff09;&#xff0c;是连接电脑与设备的一种序列总线标准&#xff0c;也是一种输入输出&#xff08;I/O&#xff09;连接端口的技术规范&#xff0c;广泛应用于个人电脑和移动…

关于大模型学习中遇到的4

来源&#xff1a;网络 相关学习可查看文章&#xff1a;Transformer and Pretrain Language Models3-4​​​​​​​ 什么是MLP? MLP是多层感知器&#xff08;Multilayer Perceptron&#xff09;的缩写&#xff0c; 多层感知机&#xff08;MLP&#xff09;是一种人工神经网…

【C++】初步认识基于C的优化

C祖师爷在使用C语言时感觉到了不方便的一些点&#xff0c;于是一步一步改进优化&#xff0c;最后形成了C 本文将盘点一下基于C的语法优化 目录 命名空间&#xff1a;命名空间定义&#xff1a;命名空间使用&#xff1a; C输入&输出&#xff1a;cout&#xff1a;endl&#…

vue项目开发的完整流程

一.构建vue.js项目 1. 安装node https://nodejs.org/en/ 下载完成后&#xff0c;下一步–>下一步–>安装完成 验证node是否安装成功: 打开命令行(windows)或终端(mac),在命令行(终端)中输入&#xff1a; node -v 如果提示出版本信息则说明node安装成功 npm -v 如果提示出…

使用django-admin来做erp,是否需要使用缓存数据库

需求: 因为添加了手机字段作为加密方式存储&#xff0c; 每次管理员查看所有订单时&#xff0c;将会进行手机字段的解密&#xff0c;那么在这个时候就会消耗多几秒. 那么计划提供一个缓存数据库给django结论&#xff1a;仅仅使用django admin&#xff0c;不需要使用缓存 1&…

C语言每日一题(47)两数相加II

力扣 445 两数相加II 题目描述 给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数字都不会以零开头。 示例1&#xff1a; 输入&#xff…

全覆盖规划算法学习笔记-------

ROS全覆盖规划算法 通过对比提供的ROS全覆盖规划算法&#xff1a;确定Boustrophedon Planner和Grid-based Local Energy Minimization Planner具备过程应用价值&#xff0c;这里选择后者进行重点研究。 参考&#xff1a; 官网 ipa_room_exploration - ROS Wiki Indoor Cover…

(2024,强化学习,扩散,奖励函数)扩散模型的大规模强化学习

Large-scale Reinforcement Learning for Diffusion Models 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 3. 方法 3.1. 使用多步骤 MDP 的策略梯度 3.2. 基于分布的奖励函…

2023 中国互联网公司 Top 100 排行榜

中国互联网协会发布了《中国互联网企业综合实力指数&#xff08;2023&#xff09;》报告&#xff0c;来源&#xff1a;https://www.isc.org.cn/article/18458024914186240.html 预览如下&#xff1a; 这份报告总结了互联网公司的排名&#xff0c;毫不意外&#xff0c;腾讯、阿里…

设计模式⑧ :管理状态

文章目录 一、前言二、Observer 模式1. 介绍2. 应用3. 总结 三、Memento 模式1. 介绍2. 应用3. 总结 四、State 模式1. 介绍2. 应用3. 总结 参考文章 一、前言 有时候不想动脑子&#xff0c;就懒得看源码又不像浪费时间所以会看看书&#xff0c;但是又记不住&#xff0c;所以决…

MySQL常用函数解读:从基础到进阶的全方位指南

MySQL提供了丰富的函数库来满足各种数据处理需求。这些函数不仅简化了复杂的数据操作&#xff0c;还提高了数据处理的效率和准确性。 在本文中&#xff0c;我们来看一下MySQL中的一些常用函数。这些函数涵盖了字符串处理、数值计算、日期和时间操作等多个方面&#xff0c;是数据…

大势浏览器DasViewer的底图能否改为卫星底图?

支持的。官网3.2.4版本tif格式的影像图可以加进来。 DasViewer是由大势智慧自主研发的免费的实景三维模型浏览器,采用多细节层次模型逐步自适应加载技术,让用户在极低的电脑配置下,也能流畅的加载较大规模实景三维模型,提供方便快捷的数据浏览操作。 #DasViewer##实景三维##三…

写了7年代码,第一次见这么狗血的小Bug!

大家好&#xff0c;我是程序员鱼皮。 孽起 Bug 年年有&#xff0c;今年特别多。前段时间给大家分享过一个 特别坑的小 Bug&#xff0c;结果这两天我个倒霉蛋又遇到一个特别离谱的 Bug&#xff0c;有多离谱&#xff1f;大家可以看看视频&#xff1a;https://www.bilibili.com/vi…

23111 C++ day1

思维导图 提示并输入一个字符串&#xff0c;统计该字符中大写、小写字母个数、数字个数、空格个数以及其他字符个数 要求使用C风格字符串完成 #include <iostream> #include<array>using namespace std;int main() {int a0,A0,num0,space0,other0;array<char…