LeetCode HOT 100 —— 215.数组中的第K个最大元素

news2024/11/26 9:37:27

题目

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k个不同的元素。
你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。

在这里插入图片描述

思路

一.暴力法:

class Solution{
	public int findKthLargest(int[] nums){
		int len = nums.length;
		Arrays.sort(nums);
		return nums[len - k];
	}	
}

二:优先队列(堆)

「优先队列」主要能解决两个问题:

  • 用来排序(堆排序

以大根堆(升序)为例:

(1)首先将待排序数组构造成一个大根堆(每次插入新结点和父节点对比,不断向上调整,保证大根堆结构,注意要按照顺序插,不能左子树为空直接插在右子树的位置 ),此时数组最大值就是堆顶元素
(2)将堆顶元素和末尾元素交换,此时数组最大值就是末尾元素,剩余待排序元素个数为n-1
(3)将剩余的n-1个数再构造成大根堆(向下调整),再讲堆顶元素和n-1位置的元素交换,反复进行,最终得到有序数组

这里给个堆排序例子:
1.构造堆:每次插入新结点和父节点对比,保持大根堆特性
在这里插入图片描述
2.堆首尾交换最大值再构造堆:将最大值固定到末尾,将剩余的数继续构造成大根堆
在这里插入图片描述

  • 用来解决TopK问题(找出前/第k个最大/最小的元素)

(1)小根堆(根节点最小)用于降序排序,所以求最大的前k个数用小根堆
(2)大根堆(根节点最大)用于升序排序,所以求最小的前k个数用大根堆

☆注意点:java自带的优先队列PriorityQueue默认自然排序(升序)是小根堆,要区分一个东西,小根堆用于降序排序(因为根节点是最小的,所以固定的末尾值是最小的,最后的顺序就是降序),但是用优先队列实现小根堆要用升序定义,因为优先队列是升序时才能保证先出的是最小值(即小根堆中每次固定最小值,保证最终是降序排序的序列)

回到本题,本题中要求的是求出第k大的元素,因此建立一个有k个元素的小根堆,根据当前队列元素个数或当前元素与栈顶元素的大小关系进行分情况讨论:

  • 当优先队列元素不足 k 个,可将当前元素直接放入队列中
  • 当优先队列元素达到 k 个,并且当前元素大于栈顶元素(栈顶元素必然不是答案),可将当前元素放入队列中,然后内部调整堆结构
  • 最终取堆顶元素就是答案(因为小根堆的堆顶是最小值,左右节点均大于根节点,而容量为k个元素,说明前面有k-1个元素比根节点大,即满足了第k大的元素这个要求

java代码如下:

class Solution {
	public int findKthLargest(int[] nums, int k){
		PriorityQueue<Integer> q = new PriorityQueue<>((a,b) -> a - b);//升序定义优先队列,实现小根堆
		for(int x : nums){
			if(q.size() < k || q.peek() < x){
				q.add(x);
			}
			if(q.size() > k){
				q.poll();
			}
		}
		return q.peek();
	}
}

三:快速选择算法: 借助快排的子过程partition的分治操作

「快速选择」 是基于 「快速排序」 思想的用于解决TopK问题的算法,「快速选择」可以通过一次遍历,确定一个元素在排序以后的位置

对于给定数组,求解第 k 大元素,且要求线性复杂度O(n),正解为使用「快速选择」做法

基本思路与「快速排序」一致,每次敲定一个基准值 x,根据当前与 x 的大小关系,将范围在 [l,r]nums[i] 划分为到两边

同时利用,利用题目只要求输出第 k 大的值,而不需要对数组进行整体排序,只需要根据划分两边后,第 k 大数会落在哪一边,来决定对哪边进行递归处理即可

java代码如下:

class Solution {
	int[] nums;
	int quickSelect(int l, int r,int k){
		if(l == r){
			return nums[k];
		}
		int x = nums[l];//基准枢轴
		int i = l - 1;
		int j = r + 1;
		//以升序为例
		while( i < j){
			do{
				i++;//从前往后找,找到第一个比基准元素大的位置
			} while(nums[i] < x);
			
			do{
				j--;//从后往前找,找到第一个比基准元素小的位置
			} while(nums[j] > x);
			
			if(i < j) swap(i,j);//交换i和j的位置
		}
		if( k <= j){//如果k在前半区间,因为j和i交换了位置
			return quickSelect(l, j, k);
		} else {//如果k在后半区间
			return quickSelect(j+1, r, k);
		}
	}
		
	void swap(int i, int j){
		int c = nums[i];
		nums[i] = nums[j];
		nums[j] = c;
	}
	
	public int findKthLargest(int[] nums, int k){
		this.nums = nums;//需要将外界的题目中的nums作为参数传入进来
		int n = nums.length;
		return quickSelect(0, n-1, n-k);
	}
}

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

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

相关文章

计算机研究生就业方向之去大厂做人工智能

我一直跟学生们说你考计算机的研究生之前一定要想好你想干什么&#xff0c;如果你只是转码&#xff0c;那么你不一定要考研&#xff0c;至少以下几个职位研究生是没有啥优势的&#xff1a; 1&#xff0c;软件测试工程师&#xff08;培训一下就行&#xff09; 2&#xff0c;前…

ARM32汇编逆向分析基础

寄存器和指令基本格式 寄存器 寄存器名称寄存器描述R0函数的第1个参数, 以及保存函数返回的结果R1 - R3保存函数的第2~4个参数R4 – R8通用寄存器&#xff0c;其中R7在系统调用时存储调用号R9平台相关R10通用寄存器, 可用于保存局部变量R11/FP栈帧指针, 用于记录栈帧R12过程间…

欣奥诚分享:企业最应避讳这八类广告宣传词汇

广告宣传中&#xff0c;企业最应避讳这八类词汇 众所周知&#xff0c;拥有一个朗朗上口、脍炙人口的广告标语、广告口号&#xff0c;对于企业战略部署、发展壮大具有最要作用。一个好的广告标语&#xff0c;不仅可以传达产品买点、展现品牌魅力&#xff0c;激发购买欲望&#…

安装多版本node

一、安装多版本node的原因&#xff1a; 在项目开发过程中&#xff0c;不同项目使用的nodejs版本不同&#xff0c;有时会因为node版本过高或太低&#xff0c;导致报错&#xff1b; 解决方式 利用nvm进行管理&#xff08;本文使用此种方式&#xff09;配置环境变量&#xff08;如…

iOS 组件化开发----(一)图片资源管理的方式

1.直接拖拽到工程&#xff0c;勾选Target membership 1&#xff09;Resource 的使用方式 将文件直接拖入到工程目录下, 并告诉Xcode打包项目时候把这些图片文件打包进去. 这样在应用的".app"文件夹中就有这些图片. 在项目中, 读取这些图片可以通过以下方式来获取图片…

JavaWeb开发(一)——maven仓库

一、maven仓库 1、maven的定义 Maven 是一个项目管理工具&#xff0c;可以对 Java 项目进行构建、依赖管理。 2、maven的约定配置 -- /src/main/java //项目java源代码 -- /src/main/resources //项目的资源文件&#xff0c;比如springmvc.xml -- /src/…

极狐gitlib的安装和使用

极狐gitlib的安装和使用一、实验环境二、安装部署&#xff08;不带邮箱&#xff09;三、一些操作3.1 常用命令3.2 备份3.2.1 备份文件分为两步&#xff1a;3.2.2 自定义备份位置3.3 恢复3.4 一些问题3.5 包含的组件四、使用极狐gitlib4.1 初始登录说明4.2 新建用户4.3 新建一个…

CSS之文字样式

1、字体类型设置 标签名&#xff1a;font-family注意&#xff1a;英文字体只适用于英文&#xff0c;中文字体可以适用中文和英文代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-…

Linux学习-81-Apache安装过程

17.9 Apache安装过程 Apache&#xff1a;作为LAMP架构的前端是一款功能强大&#xff0c;稳定性好的Web服务器程序&#xff0c;该服务器直接面向用户提供网站访问&#xff0c;发送网页&#xff0c;图片等文件内容。之前的名称就叫做 Apache&#xff0c;不过后来改名字叫做 httpd…

如何将Unity开发的AR程序编译到IPad/iPhone上真机运行

如何将Unity项目编译成iOS app&#xff0c;并在ipad或者iphone上真机运行呢&#xff1f;大体步骤分为三步&#xff1a; 使用Unity生成 .xcodeproj 文件使用XCode将AR APP编译到IPad/iPhone在真机上设置开发者模式和信任开发者 我的环境&#xff1a; 使用MacBook Pro 进行开发…

分布式操作系统 - 7.分布式一致性与复制管理

文章目录1.一致性与复制1.1 对象复制问题&#xff08;1&#xff09;单副本对象的同步控制&#xff08;2&#xff09;单副本同步控制方法&#xff08;3&#xff09;多副本对象的同步控制方法1.2 支持伸缩性的复制技术2.以数据为中心的一致性模型2.1 分布式数据仓&#xff08;dat…

Redis框架(五):大众点评项目 商品目录 添加Redis缓存

大众点评项目 商品目录 添加Redis缓存需求&#xff1a;基于Redis查询商品信息业务实现给商品添加缓存给店铺类型添加缓存总结和业务流程SpringCloud章节复习已经过去&#xff0c;新的章节Redis开始了&#xff0c;这个章节中将会回顾Redis实战项目 大众点评 主要依照以下几个原则…

Vue Demi是如何让你的库同时支持Vue2和Vue3的

Vue Demi是什么 如果你想开发一个同时支持Vue2和Vue3的库可能想到以下两种方式&#xff1a; 1.创建两个分支&#xff0c;分别支持Vue2和Vue3 2.只使用Vue2和Vue3都支持的API 这两种方式都有缺点&#xff0c;第一种很麻烦&#xff0c;第二种无法使用Vue3新增的组合式 API&am…

【Redis】Redis跳表与实现源码解析(Redis专栏启动)

&#x1f4eb;作者简介&#xff1a;小明java问道之路&#xff0c;专注于研究 Java/ Liunx内核/ C及汇编/计算机底层原理/源码&#xff0c;就职于大型金融公司后端高级工程师&#xff0c;擅长交易领域的高安全/可用/并发/性能的架构设计与演进、系统优化与稳定性建设。 &#x1…

Tomcat下载和安装

下载 Tomcat官网网址 我选择的是8&#xff0c;根据自己需要选择不同版本 选择64位下载 下载有点慢&#xff0c;等一会儿就行 安装 首先确认安装了JDK&#xff1a;命令行窗口输入java -version 配置Tomcat环境变量 配完之后验证是否成功。 winR->cmd->输入startup.bat…

什么是社交新零售?社交新零售的底层商业又是逻辑是什么?

一千个品牌商心中&#xff0c;有一千个新零售——自从马云2016年10月提出新零售的概念后&#xff0c;电商平台、传统商超、电商品牌、线下品牌&#xff0c;汹涌而至&#xff0c;都想搭上“新零售快车”。 新零售模式是依靠于大数据的开发应用&#xff0c;国内新零售模式发展多年…

Node.js快速入门

一、简介 1、什么是Node.js 简单的说 Node.js 就是运行在服务端的 JavaScript。 Node.js是一个事件驱动I/O服务端JavaScript环境&#xff0c;基于Google的V8引擎&#xff0c;V8引擎执行Javascript的速度非常快&#xff0c;性能非常好。 2、Node.js有什么用 如果你是一个前端程序…

【有料c++题目周刊 | 第一期】希腊诸神

文章目录第一题&#xff1a;珀耳修斯点金题目描述输入描述输入示例输出描述输出示例解题思路&C题解第二题&#xff1a;女神赫拉题目描述输入描述输入示例输出描述输出示例解题思路&C题解第一题&#xff1a;珀耳修斯点金 题目描述 某希腊神话故事中&#xff0c;有一个…

物联网通信技术|课堂笔记week2-2|9月7日·21日

sudo ifconfig bridge101 hw ether 9e:3e:53:38:45:66 目录 Linux网络管理命令 (1)route (2)ip (3)netstat (4)ping ​​​​​​两台电脑连起来后ping不通? (5)telnet (6)ssh (7)wget Linux网络管理命令 (1)route 路由为互联网的中转站 静态路由 动态路由 rout…

Go代码审计学习(一)

文章目录Vulnerability-goapp/assets// 根目录/login/new/top/profile/profile/edit/upload/post /timeline/timeline/searchpost/adminconfirm /adminlogin /adminusersCSRF网上有关Go的代码审计好少哇&#xff0c;能找到的文章也不多&#xff0c;害&#xff0c;没办法也得学 …