【算法训练-数组 三】数组中的第K个最大元素(TOPK问题|寻找第K大)

废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【寻找第K大】,使用【数组】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为:目标公司+最近一年+出现频率排序,由高到低的去牛客TOP101去找,只有两个地方都出现过才做这道题(CodeTop本身汇聚了LeetCode的来源),确保刷的题都是高频要面试考的题。
在这里插入图片描述

名曲目标题后,附上题目链接,后期可以依据解题思路反复快速练习,题目按照题干的基本数据结构分类,且每个分类的第一篇必定是对基础数据结构的介绍

数组中的第K个最大元素【MID】

一道中等难度使用快排可以解决的题

题干

在这里插入图片描述

输入:
[1,3,5,2,2],5,3返回值:
2
输入:
[10,10,9,9,8,7,5,6,4,3,4,2],12,3返回值:
9说明:
去重后的第3大是8,但本题要求包含重复的元素,不用去重,所以输出9      

解题思路

使用快速排序的思路来解决,快速排序(Quick Sort)是一种基于分治思想的排序算法,它通过将数组分成较小和较大的两部分,并分别对这两部分进行排序,最终将整个数组排序。快速排序是一种高效的排序算法,通常在平均情况下具有较快的执行速度。

下面是快速排序的基本思想和步骤:

  1. [划分]选择基准元素(Pivot): 从数组中选择一个元素作为基准元素。

  2. [划分]划分(Partition): 将数组分成两部分,使得基准元素左边的元素都小于等于基准元素,右边的元素都大于基准元素。这一步骤通常称为“划分”。

  3. [解决]递归排序: 递归地对基准元素左边和右边的子数组进行排序。也就是说,对小于基准元素的子数组和大于基准元素的子数组分别执行快速排序。

  4. [合并] 合并: 由于子数组都是在原数组中进行排序,所以最终整个数组也就被排序了。

这些步骤使得较大问题被分解成较小的子问题,这些子问题又能通过递归地应用快速排序来解决。在最好情况下,每次划分都能将数组均匀分成两半,这使得算法的时间复杂度为O(n log n)。

然而,需要注意的是,快速排序的性能高度依赖于基准元素的选择。最坏情况下,如果每次划分都使数组分成极不平衡的两部分,算法的时间复杂度可能会退化到O(n^2)。为了应对这种情况,通常可以选择合适的基准元素,如随机选择或者采用三数取中等方法。

总之,快速排序是一种常用且高效的排序算法,尤其适用于大规模数据的排序。

代码实现

给出代码实现基本档案

基本数据结构数组
辅助数据结构
算法快速排序(分治算法)、二分查找
技巧双指针

import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可*** @param a int整型一维数组* @param n int整型* @param K int整型* @return int整型*/public int findKth (int[] a, int n, int K) {return quikSort(a, 0, n - 1, K);}public int quikSort(int[] a, int start, int end, int K) {// 找到基准元素的位置,这个位置是第 pivot+1(因为数组下标从0开始) 大的元素int pivot = partion(a, start, end);if (K == pivot + 1 ) {// 正好命中return a[pivot]  ;} else if (K < pivot + 1) {// K小于基准位置,说明它是更大的数,在基准位置左边搜索return quikSort(a, start, pivot - 1, K);} else {// K大于基准位置,说明它是更小的数,在基准位置右边搜索,return quikSort(a, pivot + 1, end, K );}}// 获取一个基准元素,倒排,所以大于基准元素的数在左,小于基准元素的数在右private int partion(int[] a, int start, int end) {int pivotValue = a[start];int i = start, j = end;while (i != j) {// (a[j]只有大于基准元素才停止,因为大的放基准元素左边while (a[j] <= pivotValue && i < j) {// 一定要j先走,因为j先走ij就会在j的位置交汇,而基准元素的左边一定要比自己大,所以为了保证后续基准元素交换正确,一定要保证交汇位置元素值大于等于基准元素,所以要优先满足j的条件(即找到大于基准元素的值并停下),如果i先走,在靠近交互点时,i会越过大于基准元素的值与j交汇。j--;}// (a[i]只有小于基准元素才停止,因为大的放基准元素左边while (a[i] >= pivotValue && i < j) {i++;}if (i < j) {swap(a, i, j);}}// 全部交换完后,基准元素交换swap(a, start, j);return j;}// 辅助函数,交换数组元素private void swap(int[] a, int i, int j) {int temp = a[i];a[i] = a[j];a[j] = temp;}
}

复杂度分析

快速排序的时间复杂度和空间复杂度如下:

时间复杂度:

  • 平均情况: 在平均情况下,快速排序的时间复杂度为O(n log n),其中n是待排序数组的长度。这是因为每次划分都能将数组大致均匀地分成两部分,导致递归的深度大约为log n,而每次划分的过程需要O(n)的时间。

  • 最坏情况: 在最坏情况下,如果每次划分都导致一个极不平衡的分割(例如每次选取的基准元素都是当前子数组的最大或最小元素),那么快速排序的时间复杂度可能退化到O(n^2)。这是因为需要执行n次划分,每次划分都需要O(n)的时间。为了避免最坏情况,通常采用随机选择基准元素或者三数取中法来减少极端情况的发生。

  • 最好情况: 快速排序的最好情况时间复杂度为O(n log n),与平均情况相同。这种情况发生在每次划分都能将数组准确地分成相等的两部分时。

空间复杂度:

快速排序的空间复杂度主要取决于递归调用的深度和每次划分所使用的额外空间。

  • 递归调用的深度: 在递归调用中,每次只需要保存一个基准元素的索引和部分数组的边界信息。因此,递归调用的深度为O(log n)

  • 每次划分所使用的额外空间: 每次划分需要O(1)的额外空间来存储基准元素和进行交换。

综合考虑,快速排序的空间复杂度为O(log n)。这是因为虽然递归调用的深度为O(log n),但在每层递归中所需的额外空间是常数级别的。这使得快速排序在空间上比某些其他排序算法(如归并排序)更加节省。

拓展知识:分治算法

分治法是一种解决问题的算法设计范式,它将一个问题分解成多个相似的子问题,然后解决这些子问题,并将它们的解合并以得出原始问题的解。分治法的核心思想是将大问题分解成更小的、相似的子问题,通过解决子问题来解决原始问题。

分治法通常包含三个步骤:分解(Divide)、解决(Conquer)、合并(Combine)。

  1. 分解(Divide): 将原始问题划分为更小、相似的子问题。这一步骤通常是递归地进行的,即将问题逐步分解为更小规模的子问题。

  2. 解决(Conquer): 递归地解决子问题。当子问题足够小,可以直接求解时,就停止分解,转而解决这些子问题。

  3. 合并(Combine): 将子问题的解合并以得出原始问题的解。这是分治法的关键步骤,将各个子问题的解整合起来形成更大问题的解。

分治法通常用于解决一些可以被分解成相似子问题的问题,如排序、搜索、求解最短路径等。典型的分治算法包括归并排序快速排序。以下是一个分治法的示例:

归并排序:

  1. 分解(Divide): 将数组分成两半,分别对这两半进行排序。

  2. 解决(Conquer): 对分解得到的子数组递归地进行排序,直到子数组长度足够小。

  3. 合并(Combine): 将排好序的子数组合并,得到完整的有序数组。

分治法的优点在于它可以将问题分解成独立的子问题,每个子问题的求解都相对简单。这使得算法设计和理解变得更加清晰。然而,分治法有时会在子问题的合并阶段引入额外的开销,因此在设计分治算法时需要权衡分解和合并的成本。

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

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

相关文章

九、适配器模式

一、什么是适配器模式 适配器模式&#xff08;Adapter&#xff09;的定义如下&#xff1a;将一个类的接口转换成客户希望的另外一个接口&#xff0c;使得原本由于接口不兼容而不能一起工作的那些类能一起工作。 适配器模式&#xff08;Adapter&#xff09;包含以下主要角色&…

WebGPT VS WebGPU

推荐&#xff1a;使用 NSDT编辑器 快速搭建3D应用场景 随着WebGPU的引入&#xff0c;Web开发发生了有趣的转变&#xff0c;WebGPU是一种新的API&#xff0c;允许Web应用程序直接访问设备的图形处理单元&#xff08;GPU&#xff09;。这种发展意义重大&#xff0c;因为 GPU 擅长…

【MySQL】用户管理

之前我们一直都使用root身份来对mysql进行操作&#xff0c;但这样存在安全隐患。这时&#xff0c;就需要使用MySQL的用户管理 目录 一、用户 1.1 用户信息 1.2 添加用户 1.3 删除用户 1.4 修改用户密码 二、用户权限 2.1 赋予授权 2.2 回收权限 一、用户 1.1 用户信息…

【Axure高保真原型】中继器网格图片拖动摆放

今天和大家分享中继器网格图片拖动摆放的原型模板&#xff0c;我们可以通过鼠标拖动来移动图片&#xff0c;拖动过程其他图标会根据图片拖动自动排列&#xff0c;松开鼠标是图片停放在指定位置&#xff0c;其他图标自动排列。那这个模板是用中继器制作的&#xff0c;所以使用也…

[机器学习]分类算法系列①:初识概念

目录 1、概念 2、数据集介绍与划分 2.1、数据集的划分 2.2、sklearn数据集介绍 2.2.1、API 2.2.2、分类和回归数据集 分类数据集 回归数据集 返回类型 3、sklearn转换器和估计器 3.1、转换器 三种方法的区别 3.2、估计器 3.2.1、简介 3.2.2、API 3.3、工作流程 …

【软考】系统集成项目管理工程师(一)信息化基础知识【6分】

一、信息与信息系统 1、信息技术 为解决信息的采集、加工、存储、传输、处理、计算、转换、表现等问题而不断繁荣发展 核心-传输技术&#xff08;通常指通信、网络等&#xff09; 2、信息的质量属性 特点&#xff1a;客观性、普遍性 属性描述精确性对事物状态描述的精准程度…

图书馆项目Java阅览室管理系统jsp源代码MySQL

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 图书馆项目 系统有1权限&#xff1a;管理员 用所技术…

Centos7 安装 docker

1、前提条件 目前&#xff0c;CentOS 仅发行版本中的内核支持 Docker。Docker 运行在CentOS7 (64)上&#xff0c; 要求系统为64位、Linux系统内核版本为 3.8以上 查看自己系统的内核 cat /etc/redhat-release 或 uname -r 2、卸载旧版本 旧版本的 Docker 的名称为docker或doc…

【注册岩土】Python土力学与基础工程计算.PDF-摩尔-库伦强度理论

8.3 Python求解 Python求解代码如下&#xff1a; 1.import math 2. 3.sigma1 300 # 最大主应力&#xff0c;单位 kPa 4.sigma3 100 # 最小主应力&#xff0c;单位 kPa 5.alpha 30 # m-n面与最小主应力方向夹角&#xff0c;单位度 6. 7.rad_alph…

Matlab图像处理-图像旋转

基本概念 图像的旋转变换属于图像的位置变换&#xff0c;通常是以图像的中心为原点&#xff0c;将图像上的所有像素都旋转一个相同的角度。旋转后&#xff0c;图像的大小一般会改变。图像的旋转变换是指以图像的中心为原点&#xff0c;将图像上的所有像素都旋转同一个角度的变…

ubuntu系统安装tensorRT-8.6.1版本(2023-8月最新版)

目录 前言pip安装可能出现的报错&#xff1a; tar.gz安装 前言 看了无数教程和b站视频&#xff0c;啊啊啊啊啊啊啊啊啊啊啊tensorRT要我狗命啊。我要写全网tensorRT最全的博客!!! 总体来说成功安装方式有两种&#xff0c;pip安装和tar.gz安装&#xff08;其实官网安装方式居多…

Python基础算法——反转链表

视频详解&#xff1a;https://www.bilibili.com/video/BV1sd4y1x7KN/?spm_id_from333.788&vd_source11069f01f7471094186b646e3a184ca3 一、反转链表 LeetCode 206题&#xff1a;https://leetcode.cn/problems/reverse-linked-list/description/ 给你单链表的头节点 h…

NTP时钟同步服务器

目录 一、什么是NTP&#xff1f; 二、计算机时间分类 三、NTP如何工作&#xff1f; 四、NTP时钟同步方式&#xff08;linux&#xff09; 五、时间同步实现软件&#xff08;既是客户端软件也是服务端软件&#xff09; 六、chrony时钟同步软件介绍 七、/etc/chrony.conf配置文件介…

26.仪表板侧边栏菜单

效果 源码 <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Sidebar Menu</title> <link rel="stylesheet" type="text/css"…

微服务学习资料

文章目录 参考资料一. 微服务概述1. CAP理论2. BASE理论3. SpringBoot 与 SpringCloud对比 二. 服务注册&#xff1a;Zookeeper,Eureka,Nacos,Consul1. Nacos两种健康检查方式&#xff1f;2. nacos中负责负载均衡底层是如何实现的3. Nacos原理4. 临时实例和持久化(非临时)实例 …

第三届计算机、物联网与控制工程国际学术会议(CITCE 2023)

第三届计算机、物联网与控制工程国际学术会议&#xff08;CITCE 2023) The 3rd International Conference on Computer, Internet of Things and Control Engineering&#xff08;CITCE 2023) 第三届计算机、物联网与控制工程国际学术会议&#xff08;CITCE 2023&#xff09;…

相同二叉树判断

目录 题目题目要求示例 解答方法一、实现思路时间复杂度和空间复杂度代码 方法二、实现思路时间复杂度和空间复杂度代码 题目 相同二叉树判断 题目要求 题目链接 示例 解答 方法一、 递归 实现思路 如果两棵树从根结点一起访问&#xff0c;当有一个结点不相等时就返回f…

自动化运维工具—Ansible

一、Ansible概述1.1 Ansible是什么1.2 Ansible的特性1.3 Ansible的特点1.4 Ansible数据流向 二、Ansible 环境安装部署三、Ansible 命令行模块&#xff08;1&#xff09;command 模块&#xff08;2&#xff09;shell 模块&#xff08;3&#xff09;cron 模块&#xff08;4&…

【Tkinter系列07/15】小部件Message、下拉菜单、移动窗

17. 小部件Message 此小部件类似于小部件 &#xff08;请参见第 12 节 “标签小部件”&#xff09;&#xff0c;但它适用于 在多行上显示消息。所有文本将 以相同的字体显示;如果需要显示文本 使用多种字体&#xff0c;请参见第 24 节 “文本小部件”。Label 创建新构件作为子…

Linux安装Portainer(简洁版)

项目简介Docker安装 1.安装命令&#xff1a;curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun2.启动&#xff1a;systemctl start docker3.停止&#xff1a;systemctl stop docker4.重启&#xff1a;systemctl restart docker5.开机启动&#xff1a;system…