LC215. 数组中的第K个最大元素
题目介绍
- 数组中的第K个最大元素
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
解题思路
思路一
求数组中第k
大的元素,常规思路肯定是先排序,然后再取第k大的元素。采用java官方自带的Arrays.sort()
方法,该方法底层在jdk1.8以后采用的是双轴快排,时间复杂度一般能保持在O(NlogN)
,但面试中碰到这种题时肯定不能用,不然就回家等通知了。
思路二
快排虽然快,但是在遇到特殊的测试用例(数组完全有序或完全逆序)时,递归树会退化成链表。在每次快排前定义基准值时,采用随机数策略,防止切分数组时出现极端情况,导致时间复杂度为O(N^2)
。快排模板最好能背来,面试手撕代码时很有用。
在选基准值时,随机交换数组中下标为0的元素和它后面的任意元素的位置。
思路三
采用堆排序,构建大顶堆,排序一次能得到最大值,那排序第k次得到的必然是该数组中第k大的元素。
代码实现
- 直接调用API:
class Solution {// 数组元素可重复,排序后找第K个最大的,排序后,第k大的元素在nums[nums.length - k]public int findKthLargest(int[] nums, int k) {// 调API法,不推荐Arrays.sort(nums);return nums[nums.length - k];}
}/**时间:O(nlogn),默认sort使用的是快排空间:O(logn),快排中递归调用栈空间为logn*/
- 快速排序:
public class LC_215 {public int findKthLargest(int[] nums, int k) {int len = nums.length;int left = 0, right = len - 1;// 第 k 大元素的下标是 len - kint target = len - k;while(true) {int index = partition(nums, left, right);if(index == target) {return nums[index];} else if (index > target) {right = index - 1;} else {left = index + 1;}}}public int partition(int[] nums, int left, int right) {// 在区间随机选择一个元素作为基准值// 会随机生成一个整数,这个整数的范围就是int类型的范围-2^31 ~ 2^31-1,// 但是如果在nextInt()括号中加入一个整数a,那么,这个随机生成的随机数范围就变成[0,a)int randomIndex = new Random().nextInt(right - left + 1) + left;swap(nums, left, randomIndex);int pivot = nums[left];int i = left, j = right;while(i < j) {while(i < j && nums[j] >= pivot) j--;while(i < j && nums[i] <= pivot) i++;if(i < j)swap(nums, i, j);}// 循环结束,把基准数移到i下标,基准值位置确定swap(nums, i, left);return i;}public void swap(int[] nums, int i, int j) {int tmp = nums[i];nums[i] = nums[j];nums[j] = tmp;}
}/**时间:O(N),N是数组的长度;空间:O(1),仅申请了常数个变量;
*/
- 堆排序:
public class LC_215_2 {public int findKthLargest(int[] nums, int k) {int heapSize = nums.length;// 构建大顶堆(建立的同时已调整成大顶堆)buildMaxHeap(nums, heapSize);// 上面建堆完成,nums[0]为最大元素// 逐个删除堆顶元素,直到删除了 k-1 个for(int i = nums.length - 1; i >= nums.length - k + 1; i--) {// 先把堆的最后一个元素与堆顶元素交换,交换后,堆被破坏,需要调整结点满足堆swap(nums, 0, i);// 相当于删除堆顶元素(最大值),heapSize--;maxHeapify(nums, 0, heapSize);}return nums[0];}// 建立大顶堆public void buildMaxHeap(int[] arr, int heapSize) {// 从最后一个非叶子节点开始调整每一个结点的子树for(int i = heapSize >> 1; i >= 0; i--){maxHeapify(arr, i, heapSize);}}// 判断当前结点(下标为i)是否需要调整public void maxHeapify(int[] arr, int i, int heapSize) {// 当前结点i的左右孩子的下标int left = i * 2 + 1, right = i * 2 + 2;// max暂存当前根左右三个结点的最大值int max = i;// 如果左孩子在数组内,且比当前结点大,最大值暂存左孩子if(left < heapSize && arr[left] > arr[max]) max = left;// 如果右孩子在数组内,且比当前最大值还要大,最大值暂存右孩子if(right < heapSize && arr[right] > arr[max]) max = right;// 上面两个if完了后,如果最大值不是当前结点i,则交换当前结点和当前max所指向的孩子结点if(max != i) {swap(arr, i, max);// 交换了当前结点和孩子结点,因此可能下面的子树堆性质被破坏,所以对孩子的子树进行调整// 那么当前结点则为max了,进行递归maxHeapify(arr, max, heapSize);}}public void swap(int[] nums, int i, int j) {int tmp = nums[i];nums[i] = nums[j];nums[j] = tmp;}
}/**时间:O(NlogN),建堆要遍历一遍数组,时间代价为O(N);需要删除k-1次堆尾元素,每次删除的时间代价是O(logN),故删除的总代价为O(klogN)。因为k<N,所以监禁时间复杂度为O(logN)空间:O(logN),递归调用栈所使用的空间。
*/
LC215. 数组中的第K个最大元素相关推荐
- 在数组中查找第k个最大元素_查找数组中每个元素的最近最大邻居
在数组中查找第k个最大元素 Problem statement: 问题陈述: Given an array of elements, find the nearest (on the right) g ...
- 215.数组中的第K个最大元素/347. 前 K 个高频元素
2020-05-25 1.题目描述 数组中的第K个最大元素 2.题解 1.使用冒泡排序 2.使用快速排序 3.优先队列(内部是用堆来实现的) 3.代码 class Solution { public: ...
- 数组中的第K个最大元素
数组中的第K个最大元素 在未排序的数组中找到第k个最大的元素.请注意,你需要找的是数组排序后的第k个最大的元素,而不是第k个不同的元素. 示例 输入: [3,2,1,5,6,4] 和 k = 2 输出 ...
- 【LeetCode】【HOT】215. 数组中的第K个最大元素(优先队列)
[LeetCode][HOT]215. 数组中的第K个最大元素 文章目录 [LeetCode][HOT]215. 数组中的第K个最大元素 package hot;import java.util.Co ...
- 215. 数组中的第 K个最大元素
215. 数组中的第 K个最大元素 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数 组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5 ...
- LeetCode——215,数组中的第K个最大元素(分治法)
尹成老师带你学算法 /*** \* Created: liuhuichao* \* Date: 2020/1/27* \* Time: 11:32 上午* \* Description: 数组中的第K ...
- 力扣(LeetCode)215. 数组中的第K个最大元素(C语言)
一.环境说明 本文是 LeetCode 215题 : 数组中的第K个最大元素,使用c语言实现. 快速选择.查找无序数组的利器! 测试环境:Visual Studio 2019. 二.代码展示 void ...
- ⭐算法入门⭐《哈希表》中等05 —— LeetCode 215. 数组中的第K个最大元素
文章目录 一.题目 1.题目描述 2.基础框架 3.原题链接 二.解题报告 1.思路分析 2.时间复杂度 3.代码详解 三.本题小知识 四.加群须知 一.题目 1.题目描述 给定整数数组nums和 ...
- leetcode-215 数组中的第K个最大元素
在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 输出: 5 ...
最新文章
- 用户管理之用户的查询获取
- windows主要鼠标消息
- markdown demo 学习
- 第一章:1.2.3 LTI系统研究方法与本章小结
- 2020蓝桥杯省赛---java---B---5( REPEAT 程序)
- 开源巨头 SUSE 收购 Rancher Labs,云原生时代来临
- crontab 周日_linux之crontab命令
- Win10下Tensorflow(GPU版)安装趟坑实录,成功了。
- 2022春节档新片预售总票房达1.08亿
- 【java】java 随机数 Random ThreadLocalRandom SecureRandom
- C语言1013山东理工大学试题,山东理工大学史上最全C语言PPTC程序设计(2基本数据与运算).ppt...
- ld: library not found for -lcrt1.3.1.o
- python 内置变量
- html优化布局什么意思,HTML标签布局对seo的重要性(如:h1,p,alt等标签)
- 软件测试简历上实战项目:开源项目部署--litemall商城
- 液晶显示器测试软件6,屏幕坏点检测工具(Datum pixel repair)
- python画正态分布_用python的matplotlib画标准正态曲线
- Elastic Sketch: Adaptive and Fast Network-wide Measurements
- 对抖音App评论进行抓取
- strstr函数的学习