【LeetCode热题100】--215.数组中的第K个最大元素

215.数组中的第K个最大元素

image-20231014101954753

本题主要是返回数组排序之后的倒数第k个位置

方法一:基于快速排序

思路和算法

我们可以用快速排序来解决这个问题,先对原数组排序,再返回倒数第 k 个位置,这样平均时间复杂度是 O(nlog⁡n),但其实我们可以做的更快

首先我们来回顾一下快速排序,这是一个典型的分治算法。我们对数组 a[l⋯r]做快速排序:

  • 分解: 将数组 a[l⋯r]「划分」成两个子数组 a[l⋯q−1]、a[q+1⋯r],使得 a[l⋯q−1]中的每个元素小于等于 a[q]a[q]a[q],且 a[q] 小于等于 a[q+1⋯r] 中的每个元素。其中,计算下标 q也是「划分」过程的一部分。
  • 解决: 通过递归调用快速排序,对子数组 a[l⋯q−1] 和 a[q+1⋯r]进行排序。
  • 合并: 因为子数组都是原址排序的,所以不需要进行合并操作,a[l⋯r]已经有序。
  • 上文中提到的 「划分」 过程是:从子数组 a[l⋯r]中选择任意一个元素 x作为主元,调整子数组的元素使得左边的元素都小于等于它,右边的元素都大于等于它, x 的最终位置就是 q。

由此可以发现每次经过「划分」操作后,我们一定可以确定一个元素的最终位置,即 x的最终位置为 q,并且保证 a[l⋯q−1] 中的每个元素小于等于 a[q],且 a[q] 小于等于 a[q+1⋯r]中的每个元素。所以只要某次划分的 q 为倒数第 k 个下标的时候,我们就已经找到了答案。 我们只关心这一点,至于 a[l⋯q−1]和 a[q+1⋯r]是否是有序的,我们不关心

因此我们可以改进快速排序算法来解决这个问题:在分解的过程当中,我们会对子数组进行划分,如果划分得到的 q 正好就是我们需要的下标,就直接返回 a[q];否则,如果 q比目标下标小,就递归右子区间,否则递归左子区间。这样就可以把原来递归两个区间变成只递归一个区间,提高了时间效率。这就是「快速选择」算法。

class Solution {int quickselect(int[] nums, int l,int r,int k) {if(l == r ){return nums[k];}int x = nums[l],i = l - 1,j = r + 1;while(i < j){  //下面过程就是进行快速排序do {i++;}while(nums[i] < x);  //找到左区间大于x的位置do{j--;}while(nums[j] > x);  //找到右区间小于x的位置if(i<j){   //将两者进行交换int tmp = nums[i];nums[i] =  nums[j];nums[j] = tmp;}}if(k<=j){  //x比目标下标大,递归左子区间return quickselect(nums,l,j,k);}else{   //x比目标下表小,递归右子区间return quickselect(nums,j+1,r,k);}}public int findKthLargest(int[] _nums,int k){int n = _nums.length;//第K个最大及第n-k个大的(从0开始)return quickselect(_nums, 0, n-1, n-k);}
}

方法二:基于堆排序

我们也可以使用堆排序来解决这个问题——建立一个大根堆,做 k−1k - 1k−1 次删除操作后堆顶元素就是我们要找的答案。在很多语言中,都有优先队列或者堆的的容器可以直接使用

class Solution {public int findKthLargest(int[] nums,int k){int headSize = nums.length;buildMaxHeap(nums,headSize);for(int i = nums.length - 1; i>= nums.length-k+1; --i){swap(nums,0,i);--headSize;maxHeapify(nums,0,headSize);}return nums[0];}public void buildMaxHeap(int[] a,int headSize){for(int i = headSize/2; i>=0;--i){maxHeapify(a,i,headSize);}}public void maxHeapify(int[] a,int  i ,int headSize){int l = i * 2 + 1,r = i * 2 + 2,largest = i;if(l<headSize && a[l] > a[largest]){largest = l;}if(r < headSize && a[r] > a[largest]){largest = r;}if(largest != i){swap(a,i,largest);maxHeapify(a,largest,headSize);}}public void swap(int[] a,int i ,int j){int tmp = a[i];a[i] = a[j];a[j] = tmp;}
}

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

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

相关文章

npm install报--4048错误和ERR_SOCKET_TIMEOUT问题解决方法之一

一、问题描述 学习vue数字大屏加载动漫效果时&#xff0c;在项目终端页面输入全局下载指令 npm install -g json-server 问题1、报--4048错误 会报如下错误 operation not permitted......errno: -4048code:EPERMsyscall: mkdir......The operation was reiected by your op…

Qt应用开发(基础篇)——列表视图 QListView

一、前言 QListView类继承于QAbstractItemView类&#xff0c;提供了一个列表或者图标视图的模型。 视图基类 QAbstractItemView QListView效果相当于Windows文件夹右键->查看->图标和列表&#xff0c;使用setViewMode()设置视图模式&#xff0c;并且提供setIconSize()函数…

Kafka 开启SASL/SCRAM认证 及 ACL授权(一)认证

Kafka 开启SASL/SCRAM认证 及 ACL授权(一)认证。 kafka安全涉及3部份:传输加密,用户认证与授权,ZK开启ACL(Zookeeper存储了kafka的元数据以及用户信息,默认不开启acl所有用户可改,内网环境机器不对外开放可考虑使用默认不开启ZK ACL)。 官网地址:https://kafka.ap…

02_单片机及开发板介绍

单片机简介 单片机&#xff0c;又称为微控制器&#xff08;Microcontroller&#xff09;&#xff0c;是一种集成了微处理器核心、存储器、输入/输出接口及各种功能模块的集成电路芯片。它通常由中央处理器&#xff08;CPU&#xff09;、存储器、输入/输出接口以及各种外设组成&…

Java架构师缓存性能优化

目录 1 缓存的负载策略2 缓存的序列化问题3 缓存命中率低4 缓存对数据库高并发访问5 缓存数据刷新的策略5.1. 实时策略5.2. 异步策略5.3. 定时策略6 何时写缓存7 批量数据来更新缓存8 缓存数据过期的策略9 缓存数据如何恢复10 缓存数据如何迁移11 缓存冷启动和缓存预热想学习架…

ubuntu下yolov5 tensorrt模型部署

文章目录 ubuntu下yolov5 tensorrt模型部署一、Ubuntu18.04环境配置1.1 安装工具链和opencv1.2 安装Nvidia相关库1.2.1 安装Nvidia显卡驱动1.2.2 安装 cuda11.31.2.3 安装 cudnn8.21.2.4 下载 tensorrt8.4.2.41.2.5 下载仓库TensorRT-Alpha并设置 二、从yolov5源码中导出onnx文…

ES _bulk 批量操作用法

es 的 bulk 操作&#xff0c;是用来批量发送请求&#xff0c;或者理解为批量操作的。 支持4种操作 bulk 支持多种操作&#xff0c;如下create、index、update、delete。 create 如果文档不存在就创建&#xff0c;但如果文档存在就返回错误index 如果文档不存在就创建&#x…

SQL Server远程登录失败

SQL Server远程登录失败 检查SQL SERVER 是否允许远程访问. 具体步骤: 1)在远端SQL Server主机上,打开SSMS并连接数据库 2)在相应”数据库”上单击右键,选择”属性” 3)选择”连接”选项卡,检查”远程服务器连接”下,RPC服务是否选择. 设置SQL Server相关TCP连接 1.打开SQL Se…

如何建立线上线下相结合的数字化新零售体系?

身处今数字化时代&#xff0c;建立线上线下相结合的数字化新零售体系是企业成功的关键。蚓链数字化营销系统致力于帮助企业实现数字化转型&#xff0c;打通线上线下销售渠道&#xff0c;提升品牌影响力和用户黏性&#xff0c;那么具体是如何建立的&#xff1f; 1. 搭建数字化中…

SpringBoot-黑马程序员-学习笔记(五)

74.自定义bean属性绑定以及第三方bean属性绑定 自定义bean属性绑定 1.自定义一个bean Data Component public class ServerConfig {private String ipAddress;private int port;private long timeout; } 2.在yml配置文件中中定义一组值 3.在bean中进行属性绑定 加上这个注…

链路层3:VLAN的配置与分析

VLAN的帧格式 VLAN数据帧的传输 在以太网中&#xff0c;加了标签tag的VLAN数据帧我们叫做V-MAC帧&#xff0c;普通的数据帧我们叫做MAC帧。对于主机来说&#xff0c;它只认识普通的MAC帧&#xff1b;对于主机&#xff0c;V-MAC帧和MAC帧它都认。所以&#xff0c;实际上的V-MAC…

linux——多线程,线程控制

目录 一.POSIX线程库 二.线程创建 1.创建线程接口 2.查看线程 3.多线程的健壮性问题 4.线程函数参数传递 5.线程id和地址空间 三.线程终止 1.pthread_exit 2.pthread_cancel 四.线程等待 五.线程分离 一.POSIX线程库 站在内核的角度&#xff0c;OS只有轻量级进程…