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

【Hot 100 刷题计划】 LeetCode 215. 数组中的第K个最大元素 | C++ 快速选择与堆排序题解

LeetCode 215. 数组中的第K个最大元素 | C++ 快速选择与小顶堆双解法

📌 题目描述

题目级别:中等

给定整数数组nums和整数k,请返回数组中第k个最大的元素。
请注意,你需要找的是数组排序后的第k个最大的元素,而不是第k个不同的元素。

你必须设计并实现时间复杂度为O(N)O(N)O(N)的算法解决此问题。

  • 示例 1:
    输入:[3,2,1,5,6,4],k = 2
    输出:5

💡 破题思路:Top K 问题的绝代双骄

面对 Top K 问题,直接调用sort()排序(O(Nlog⁡N)O(N \log N)O(NlogN))显然不是面试官想要的。在大厂面试中,这道题的标准答案分为两个方向:追求数学极限的O(N)O(N)O(N)解法,以及应对海量工程数据的解法

🚀 解法一:快速选择算法 QuickSelect (严格 O(N) 面试满分解)

题目加粗强调了时间复杂度必须是O(N)O(N)O(N),破局的唯一解法就是快速选择算法(QuickSelect)
它的核心思想脱胎于经典的“快速排序(Quick Sort)”:

  1. 区域划分(Partition):随便挑一个基准值(Pivot),把比它的数扔到左边,比它的数扔到右边(降序划分)。
  2. 精准剪枝(灵魂所在):一次划分后,基准值就落在了最终正确的排名位置。如果我们要找的第 K 大元素的索引刚好在左半区,那我们完全不需要去管右半区,直接递归左半区即可!

因为每次都能砍掉大约一半的数据量(N+N/2+N/4+...N + N/2 + N/4 + ...N+N/2+N/4+...),它的时间复杂度收敛成了极其优雅的O(N)O(N)O(N)

💻 C++ 代码实现 (Hoare 划分模板)
classSolution{public:intfindKthLargest(vector<int>&nums,intk){// 调用 quickSelect,注意题目要求的 k 是第 k 大,对应降序数组的索引是 k - 1returnquickSelect(nums,0,nums.size()-1,k);}private:intquickSelect(vector<int>&nums,intl,intr,intk){if(l==r)returnnums[l];// 递归终止条件// 1. 选取基准值 pivot,取中间元素可避免在有序数组下退化intpivot=nums[l+(r-l)/2];inti=l-1,j=r+1;// 2. 降序划分过程 (Hoare Partition)while(i<j){doi++;while(nums[i]>pivot);doj--;while(nums[j]<pivot);if(i<j)swap(nums[i],nums[j]);}// 3. 核心剪枝:判断第 k 大的元素落在哪个区间,只去那一个区间寻找if(k-1<=j)returnquickSelect(nums,l,j,k);returnquickSelect(nums,j+1,r,k);}};

🏆 解法二:优先队列 / 小顶堆 (海量数据流最优解)

如果在面试中,面试官加上一个条件:“如果是海量数据(如 100 亿条日志),内存放不下整个数组怎么办?” 这时候 QuickSelect 就失效了,必须请出优先队列(小顶堆)。

核心思想:

我们要维护一个大小始终为KKK的小顶堆。
遍历数据流,遇到新元素直接入堆。如果堆的容量超过了KKK,就把堆里最小的元素(堆顶)踢出去。
大浪淘沙之后,等所有数据遍历完,这个大小为KKK的堆里留下的就是全场最大的KKK个数,而此时的堆顶,刚好就是这 K 个数里最小的,也就是我们要找的第 K 大的数!

💻 C++ 代码实现 (大小为 K 的小顶堆)
classSolution{public:intfindKthLargest(vector<int>&nums,intk){// C++ 默认是大顶堆,通过 greater<int> 定义为小顶堆priority_queue<int,vector<int>,greater<int>>minHeap;for(inti=0;i<nums.size();i++){minHeap.push(nums[i]);// 无脑入堆// 只要堆的大小超过了 K,就把最小的那个(堆顶)踢出去if(minHeap.size()>k){minHeap.pop();}}// 最终堆顶留下的,就是第 K 大的元素returnminHeap.top();}};
http://www.jsqmd.com/news/599183/

相关文章:

  • OpenClaw实战案例:用1个主控+3个Agent,实现SEO文章日更3篇
  • 终极游戏模组管理器:XXMI启动器让模组管理变得前所未有的简单
  • H-ui.Admin:轻量级后台开发的效率革命方案
  • 交流放大电路
  • 多模态Agent从入门到精通:AgentVista全解析,收藏这篇就够了!
  • OpenClaw AI助手本地部署完整教程
  • 保姆级教程:彻底解决Win11 CH340串口‘无法访问’问题(附2011版驱动下载与防捆绑指南)
  • 新手友好:在快马平台构建你的第一个网易方锐AI音乐调用应用
  • Linux内核中的网络子系统实现详解
  • 彻底解决AMD显卡风扇控制失效:FanControl ADLXWrapper初始化失败的终极修复指南
  • 18650锂电池热效应建模实战手记
  • Linux运维实战:高效文件处理与终端管理技巧
  • 从插件到工作流:在Coze平台实战快商通AI语音防伪接口(避坑指南+节点连接技巧)
  • 3步搞定小红书内容采集:XHS-Downloader免费无水印下载终极指南
  • League Akari:基于LCU API的模块化游戏自动化框架深度解析
  • 突破3大信息壁垒:kill-doc的高效内容获取之道
  • Protocol Buffers(.proto)实战入门:Go 生态最常用的接口定义语言
  • 我是格行招商总监张总,在物联网干了8年:2026年,这种“管道收益”副业,才值得普通人All in - 格行官方招商总部
  • TranslateGemma快速入门:一键部署企业级神经机器翻译系统
  • 告别HASH_MOD报错:手把手教你为Sharding-JDBC 5.5.0编写自定义分表算法(附完整代码)
  • metrics server和kube-state-metrics对比
  • Python异常处理最佳实践:从理论到实践
  • 如何高效管理远程BT下载:Transmission Remote GUI终极指南
  • AI安全高阶:生成式AI的安全风险与防御体系
  • 论文降AI之前要做哪些AIGC自检:完整自查流程 - 还在做实验的师兄
  • 3步上手BlueLotus_XSSReceiver:从漏洞捕获到数据解析的实战指南
  • 从测试到ISP调试:一名Camera Tuning工程师的四年转型与面试通关实录
  • 公式编辑器 latexlive
  • 用嘎嘎降AI处理学位论文全流程:从上传到验收完整教程 - 还在做实验的师兄
  • Kafka性能测试实战:从脚本使用到参数调优全解析