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

news2024/11/24 9:03:12

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.coloradmin.cn/o/1091061.html

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

相关文章

管程的介绍

一、概述 1.引入原因 信号量机制实现同步存在编写程序困难&#xff0c;易出错问题 2.概念 是一种实现进程互斥与同步的机制&#xff0c; 3.组成 共享数据结构说明、对数据结构操作的过程/函数、初始化共享数据、管程名&#xff1b; 4.特点 类似类的结构(数据对象相关操…

IDEA通过Docker插件部署SpringBoot项目

1、配置Docker远程连接端口 找到并编辑服务器上的docker.service文件。 vim /usr/lib/systemd/system/docker.service在下面ExecStart替换成下面的 ExecStart/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock2.重启docker systemctl daemon-reload s…

强化学习(Reinforcement Learning)与策略梯度(Policy Gradient)

写在前面&#xff1a;本篇博文的内容来自李宏毅机器学习课程与自己的理解&#xff0c;同时还参考了一些其他博客(懒得放链接)。博文的内容主要用于自己学习与记录。 1 强化学习的基本框架 强化学习(Reinforcement Learning, RL)主要由智能体(Agent/Actor)、环境(Environment)、…

CSS padding(填充)

CSS padding&#xff08;填充&#xff09;是一个简写属性&#xff0c;定义元素边框与元素内容之间的空间&#xff0c;即上下左右的内边距。 padding&#xff08;填充&#xff09; 当元素的 padding&#xff08;填充&#xff09;内边距被清除时&#xff0c;所释放的区域将会受到…

最新Base64注入攻击和代码分析技术

点击星标&#xff0c;即时接收最新推文 本文选自《web安全攻防渗透测试实战指南&#xff08;第2版&#xff09;》 点击图片五折购书 Base64注入攻击 Base64注入攻击的测试地址在本书第2章。 从URL中可以看出&#xff0c;参数ID经过Base64编码&#xff08;“%3d”是“”的URL编码…

Vulnhub系列靶机-Raven2

文章目录 Raven2 渗透测试1. 信息收集1.1 主机探测1.2 端口扫描1.3 目录爆破 2. 漏洞探测3. 漏洞利用3.1 msfconsole3.2 交互式shell 4. 权限提升 Raven2 渗透测试 1. 信息收集 1.1 主机探测 arp-scan -l1.2 端口扫描 nmap -p- -A 192.168.188.213通过nmap工具进行端口扫描…

LeetCode【54】螺旋矩阵

题目&#xff1a; 思路&#xff1a; 参考&#xff1a;https://blog.csdn.net/ShiXiAoLaNga/article/details/124975293 上下左右&#xff0c;四个游标&#xff0c;代表边界&#xff0c;每次遍历完一行或一列都移动游标&#xff1b;直到 down > up、right < left&#xf…

使用hugging face开源库accelerate进行多GPU(单机多卡)训练卡死问题

目录 问题描述及配置网上资料查找1.tqdm问题2.dataloader问题3.model(input)写法问题4.环境变量问题 我的卡死问题解决方法 问题描述及配置 在使用hugging face开源库accelerate进行多GPU训练&#xff08;单机多卡&#xff09;的时候&#xff0c;经常出现如下报错 [E Process…

key value存储到底有什么优势?

昨天被问到Key value存储到底有什么优势&#xff0c;当然脑子也没太转过来。正好昨天学习了B树和LSM树的差别&#xff0c;并了解到LSM树底层是可以用sstable来实现的。sstable包含一个数据块列表和一个索引块&#xff0c;数据块存储有序键镇对&#xff0c;索引块存储所有数据块…

navicate安装教程

Navicat是一款数据库管理工具&#xff0c;它支持多种数据库类型&#xff0c;包括MySQL、MariaDB、Oracle、SQL Server等。Navicat具有直观的图形用户界面和易于使用的功能&#xff0c;可以让用户轻松地管理和操作数据库。 首先&#xff0c;Navicat提供了一种简单的方法来连接到…

Linux gcc和make学习

文章目录 GCCgcc的安装gcc的工作流程 makefilemakefile的规则工作原理自动生成makefile的变量自定义变量预定义变量自动变量 模式匹配函数wildcard函数patsubst函数 伪声明 GCC gcc全程是&#xff08;GNU compiler collection CNU编译器套件&#xff09;&#xff0c;是由GNU开发…

【汇编语言学习笔记】一、基础知识

引言 汇编语言是直接在硬件之上工作的编程语言&#xff0c;首先要了解硬件系统的结构&#xff0c;才能有效的应用汇编语言对其编程。 1.1机器语言 机器语言是机器指令的集合。 机器指令展开来讲就是一台机器可以正确执行的命令。 1.2汇编语言 汇编语言的主体是汇编指令。 …

2023年中国特高压绝缘子市场规模及特高压投资完成额统计[图]

绝缘子指一般由固体绝缘材料制成&#xff0c;安装在不同点位的导体之间或导体与接地构件之间&#xff0c;是同时起到电气绝缘和机械支撑作用的器件&#xff0c;绝缘子可分为瓷绝缘子、玻璃绝缘子与复合绝缘子。特高压绝缘子指用于交流1,000kV、直流800kV及以上电压等级的绝缘子…

基于SSM框架的安全教育平台

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

QT CmakeLists配置python

这是exe目录&#xff0c;要放到这里&#xff0c;要放到这里&#xff0c;要放到这里。 find_package(PythonLibs 3.6 REQUIRED) include_directories(${PYTHON_INCLUDE_DIRS})set(PY python/libs/) set(PY_LIBS ${PY}_tkinter ${PY}python3 ${PY}python36 ${PY}python36_d) targ…

1805_emacs org-mode的归档处理

全部学习汇总&#xff1a;GreyZhang/g_org: my learning trip for org-mode (github.com) 我使用org-mode其实很多年了&#xff0c;但是使用的org-mode功能非常少而且技术自然也是很浮于表面。很多org-mode本身的功能我了解不多&#xff0c;更谈不上能够掌握。就比如说通过org维…

【DRAM存储器十五】DDR介绍-关键技术之DLL和prefetch

&#x1f449;个人主页&#xff1a;highman110 &#x1f449;作者简介&#xff1a;一名硬件工程师&#xff0c;持续学习&#xff0c;不断记录&#xff0c;保持思考&#xff0c;输出干货内容 参考资料&#xff1a;《镁光DDR数据手册》 目录 DLL 预取 DDR SDRAM的几个新增时…

Centos下编译ffmpeg动态库

文章目录 一、下载ffmpeg安装包二、编译ffmpeg三、安装yasm 一、下载ffmpeg安装包 下载包 wget http://www.ffmpeg.org/releases/ffmpeg-4.4.tar.gz解压 tar -zxvf ffmpeg-4.4.tar.gz二、编译ffmpeg 进入解压的目录 cd ffmpeg-4.4编译动态库 ./configure --enable-shared…

MyBatisPlus之基本CRUD、常用注解

文章目录 前言一、MyBatisPlus简介1.简介2.特性 二、基本CRUD1.依赖2.搭建基本结构3.BaseMapper4.使用插入删除&#xff08;1&#xff09;通过id删除记录&#xff08;2&#xff09;通过id批量删除记录&#xff08;3&#xff09;通过map条件删除记录 修改查询&#xff08;1&…

python 爬虫与协同过滤的新闻推荐系统 计算机竞赛

1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; python 爬虫与协同过滤的新闻推荐系统 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;4分 该项目较为新颖&…