分治算法(3)_快速选择_数组中的第K个最大元素

个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创

分治算法(3)_快速排序_数组中的第K个最大元素

收录于专栏【经典算法练习】
本专栏旨在分享学习算法的一点学习笔记,欢迎大家在评论区交流讨论💌

目录

温馨提示:

1. top k问题

2. 题目链接

3. 题目描述

4. 解法(快速排序)

算法思路:

代码展示:

结果分析:


温馨提示:

该问题是top k问题的一类,top k问题可以使用堆排序和快速排序解决,因为题目要求使用O(N)的时间复杂度解决该问题,所以我这里就直接使用快速排序解决,想看堆排序的宝子们可以取下面的博客查看:

数据结构之二叉树的超详细讲解(2)--(堆的概念和结构的实现,堆排序和堆排序的应用)-CSDN博客 

1. top k问题

top k一共有4中类型:

1. 求数据中第k大的数

2. 求数据中第k小的数

3. 求前k大的数

4. 求前k小的数

top k问题在我们生活中还是比较常见的,比如在王者荣耀里面,你是济南市第九吕布,那么就需要系统找到济南市第九荣耀战力的吕布并将其信息打印出来,这样你就能看到你自己是济南市第九吕布了;又比如说:你不满足于济南市第九吕布,你想拿山东省第九吕布,但是你不知道山东省第九吕布的战力是多少,这个时候你就需要查询,山东省前一百吕布的战力,这时候就是top k100问题了

解决top k问题目前有两种方法:

1. 堆排序 时间复杂度O(NlogN)--(这个可以去上面我推荐的博客,讲解的很详细,初中数学知识就行)

2. 快速选择算法 时间复杂度O(N)--(这个的具体证明可以去看算法导论,我数学不太行!) 

2. 题目链接

OJ链接 :  数组中的第K个最大元素

3. 题目描述

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

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

示例 1:

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

示例 2:

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

提示:

  • 1 <= k <= nums.length <= 105
  • -104 <= nums[i] <= 104

4. 解法(快速排序)

算法思路:

这里需要有(数组分三块,随机取key)快速排序的基础,如果还不知道的宝子们可以取看下面的博客:

分治算法(2)_快速排序_排序数组-CSDN博客 

在快排中,当我们把数组[分成三块]之后: [l, left][left + 1, right - 1][right, r], 我们可以通过计算每一个区间内的元素[个数],进而推断出我们要找的元素是在[哪一个区间]里面.

那么我们可以直接去[相应的区间]去寻找最终结果就好了.

 

代码展示:

class Solution {
public:int findKthLargest(vector<int>& nums, int k) {srand(time(NULL));return qsort(nums, 0, nums.size() - 1, k);}int qsort(vector<int>& nums, int l, int r, int k){if(l >= r) return nums[l];int key = getRandom(nums, l, r);int i = l, left = l - 1, right = r + 1;while(i < right){if(nums[i] < key) swap(nums[++left], nums[i++]);else if(nums[i] == key) i++;else swap(nums[--right], nums[i]);}int b = right - left - 1;int c = r - right + 1;if(c >= k) return qsort(nums, right, r, k);else if(b + c >= k) return key;else return qsort(nums, l, left, k - b - c);}int getRandom(vector<int>& nums, int left, int right){int r = rand();return nums[left + r % (right - left + 1)];}
};

结果分析:

在随机选择基准的情况下,期望的时间复杂度为 O(n)。这是因为在平均情况下,基准会将数组大致分成两半,这样每次递归将处理的元素数量减少大约一半。
由于每次递归的分区工作是线性的(O(n)),整个过程在期望情况下是 O(n) 的。 (具体的证明大家可以看算法导论)

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【原创】Anaconda+VScode+PySide6 完美配置Python开发环境,亲测!

准备工作 下载安装 Anaconda 下载安装Visual Studio Code 配置系统环境变量 配置Anaconda环境变量 将Anaconda安装目录及Scripts 、Library\bin 两个子目录添加到用户变量或系统变量的Path变量中。 Anaconda自带最新版Python&#xff0c;如果已经安装Python&#xff0c;建议…

Mybatis测试案例

1.创建springboot工程 创建实体类user和接口 user类 注意&#xff1a;java和mysql的对象的属性数据类型要一致 mapper接口 2.配置mybatis(连接数据库信息) # spring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver #地址url spring.datasource.urljdbc:mysql://localho…

【Python】Mistune:高效的 Python Markdown 解析器

Mistune 是一个轻量且强大的 Python Markdown 解析器。它的设计目标是兼顾速度和扩展性&#xff0c;同时兼容 CommonMark 标准。Mistune 支持多种渲染器&#xff08;Renderers&#xff09;和插件&#xff0c;能够根据需求将 Markdown 转换为 HTML、LaTeX 或自定义格式。此外&am…

Java中数组的应用

Java中数组的应用 数组数组的使用使用方式1-动态初始化数组的定义&#xff1a;数组的引用&#xff08;使用/访问/获取数组元素&#xff09;&#xff1a;快速入门案例 使用方式2-动态初始化**先声明**数组**再创建**数组使用方式1和2的比较 使用方式3-静态初始化初始化数组快速入…

[嵌入式Linux]—STM32MP1启动流程

STM32MP1启动流程 1.启动模式 STM32MP1等SOC支持从多种设备中启动&#xff0c;如EMMC、SD、NAND、NOR、USB、UART等。其中USB、UART是作为烧录进行启动的。 STM32MP1内部ROM中存储有一段出厂代码来进行判断从哪种设备中启动&#xff0c;上电后这段代码会被执行&#xff0c;这…

CPU中的寄存器是什么以及它的工作原理是什么?

在计算机科学中&#xff0c;寄存器是数字设备中的一个重要组成部分&#xff0c;它用于存储数据和指令以快速处理。寄存器充当临时存储区&#xff0c;信息可以在这里被快速访问和操作&#xff0c;以执行复杂任务。寄存器是计算机中最基础的存储类型&#xff0c;它们在帮助机器高…

【Unity】版本不一致且未升级资产,导致 Unity Sprite 2D 动画播放错误

自己的 Unity版本是 2022.3.45f1。目前折腾的这插件 2D Action RPG Engine: Mythril2D &#xff0c;推荐使用的 Unity 版本是 2021.3.18。 倒腾了这个 unity animation 动画半天&#xff0c;发现这个 animation sprite resolver 在导入动画帧的时候&#xff0c;一直都导入的是…

allegro 替换过孔

操作步骤如下 1.选择操作对象&#xff08;需要替换的过孔&#xff09;&#xff0c;右键–>Repace……–>Selected…… 2.在弹出的窗口中选择最终需要的过孔既可以

【Matlab学习日记】② 常用滤波以及噪声分析方法(上)

关注星标公众号&#xff0c;不错过精彩内容 作者 | 量子君 微信公众号 | 极客工作室 【Matlab学习日记】专栏目录 第一章 ① Sinmulink自动代码生成教程 第二章 ② 常用滤波以及噪声分析方法&#xff08;上&#xff09; 文章目录 前言一、使用滤波的目的二、常见的几种噪声和表…

算法闭关修炼百题计划(四)

仅供个人复习 1.两数相加2.寻找峰值3.寻找旋转排序数组中的最小值4.寻找旋转排序数组中的最小值II5.搜索旋转排序数组6.岛屿的最大面积7.最大数8.会议室9.最长连续序列 1.两数相加 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储…

STM32 通用同步/异步通信

一、串行通信简介 CPU与外围设备之间的信息交换称为通信。基本的通信方式有并行通信和串行通信两种。STM32单片机提供了功能强大的串行通信模块&#xff0c;即通用同步/异步收发器&#xff08;USART&#xff09;。 1.串行通信 串行通信是数据字节一位一位地依次传送的通信方式。…

毕业设计 深度学习水果识别

文章目录 1 前言2 开发简介3 识别原理3.1 传统图像识别原理3.2 深度学习水果识别 4 数据集5 部分关键代码5.1 处理训练集的数据结构5.2 模型网络结构5.3 训练模型 6 识别效果 1 前言 Hi&#xff0c;大家好&#xff0c;这里是丹成学长&#xff0c;今天做一个 基于深度学习的水果…

毕业设计——医院信息化系统原型设计

作品详情 主要功能&#xff1a; 信息化系统是以患者为中心&#xff0c;服务于重症科室医务人员&#xff0c;提高工作效率及医疗服务质量。软件主要包含了重症医学临床管理系统和中央监控站&#xff0c;重症医学临床管理系统主要实现患者床位总览、患者护理、医嘱管理、数据字典…

JS 介绍/书写位置/输入输出语法

目录 1. JS 介绍 1.1 JS 是什么 1.2 JS 的作用 1.3 JS 的组成 2. JS 书写位置 2.1 内部 JS 2.2 外部 JS 2.3 内联 JS 3. JS 注释和结束符 4. JS 输入输出语法 4.1 输入语法 4.2 输入语句 4.3 执行顺序 5. 字面量 1. JS 介绍 1.1 JS 是什么 1.2 JS 的作用 1.3 JS …

GOM引擎启动后M2提示Invalid filename报错的解决办法

在架设一个GOM引擎版本的时候&#xff0c;启动M2就提示Invalid filename&#xff0c;之后的网关就没有办法再启动了&#xff0c;研究了半天也终于是弄好了&#xff0c;其实也简单&#xff0c;就是路径设置的不对&#xff0c;所以无法完成启动&#xff0c;很多人以为在控制台设置…

国庆节刷题

10.1 C语言 10.1 C 10.2 C语言 10.2 C 10.3 C语言 10.3 C 10.4 C语言 10.4 C 10.5 C语言 10.5 C 10.6 C语言 10.6 C

如何写出Pythonic的代码?

f-string、三元操作、各种解析式、生成器装饰器的熟练运用&#xff0c;“内库”引用和函数封装再加持PEP8&#xff0c;撰写的脚本不pythonic都难。&#x1f60e; (笔记模板由python脚本于2024年10月07日 18:03:27创建&#xff0c;本篇笔记适合特别喜欢python的coder翻阅) 【学习…

手机号归属地查询-手机号归属地-手机号归属地-运营商归属地查询-手机号码归属地查询手机号归属地-运营商归属地

手机号归属地查询API接口是一种网络服务接口&#xff0c;允许开发者通过编程方式查询手机号码的注册地信息。关于快证签API接口提供的手机号归属地查询服务&#xff0c;以下是一些关键信息&#xff1a; 一、快证签API接口简介 快证签API接口可能是一个提供多种验证和查询服务…

Burp Suite为何能抓到HTTPS的明文流量,Wireshark可以吗,公司电脑的加密流量也是被监控了吗?

在前期博文《万字图文详解HTTPS协议通信过程&#xff0c;结合抓包实战解析带你一次看透HTTPS&#xff01;》中&#xff0c;我们知悉HTTPS通信内容是用会话密钥加密的&#xff0c;但不少细心的读者存在疑问&#xff1a;为何对于使用HTTPS协议的站点&#xff0c;在Burp Suite中拦…

Excel-查找和引用数据-VLOOKUP 和 HLOOKUP 函数

在 Excel 中&#xff0c;VLOOKUP 和 HLOOKUP 是用于查找和引用数据的函数。下面是它们的基本用法&#xff1a; VLOOKUP 用途&#xff1a;在表格的第一列中查找某个值&#xff0c;并返回该值所在行的指定列中的数据。 语法&#xff1a; VLOOKUP(lookup_value, table_array, …