题目介绍

  1. 数组中的第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个最大元素相关推荐

  1. 在数组中查找第k个最大元素_查找数组中每个元素的最近最大邻居

    在数组中查找第k个最大元素 Problem statement: 问题陈述: Given an array of elements, find the nearest (on the right) g ...

  2. 215.数组中的第K个最大元素/347. 前 K 个高频元素

    2020-05-25 1.题目描述 数组中的第K个最大元素 2.题解 1.使用冒泡排序 2.使用快速排序 3.优先队列(内部是用堆来实现的) 3.代码 class Solution { public: ...

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

    数组中的第K个最大元素 在未排序的数组中找到第k个最大的元素.请注意,你需要找的是数组排序后的第k个最大的元素,而不是第k个不同的元素. 示例 输入: [3,2,1,5,6,4] 和 k = 2 输出 ...

  4. 【LeetCode】【HOT】215. 数组中的第K个最大元素(优先队列)

    [LeetCode][HOT]215. 数组中的第K个最大元素 文章目录 [LeetCode][HOT]215. 数组中的第K个最大元素 package hot;import java.util.Co ...

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

    215. 数组中的第 K个最大元素 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数 组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5 ...

  6. LeetCode——215,数组中的第K个最大元素(分治法)

    尹成老师带你学算法 /*** \* Created: liuhuichao* \* Date: 2020/1/27* \* Time: 11:32 上午* \* Description: 数组中的第K ...

  7. 力扣(LeetCode)215. 数组中的第K个最大元素(C语言)

    一.环境说明 本文是 LeetCode 215题 : 数组中的第K个最大元素,使用c语言实现. 快速选择.查找无序数组的利器! 测试环境:Visual Studio 2019. 二.代码展示 void ...

  8. ⭐算法入门⭐《哈希表》中等05 —— LeetCode 215. 数组中的第K个最大元素

    文章目录 一.题目 1.题目描述 2.基础框架 3.原题链接 二.解题报告 1.思路分析 2.时间复杂度 3.代码详解 三.本题小知识 四.加群须知 一.题目 1.题目描述   给定整数数组nums和 ...

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

    在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 输出: 5 ...

最新文章

  1. 用户管理之用户的查询获取
  2. windows主要鼠标消息
  3. markdown demo 学习
  4. 第一章:1.2.3 LTI系统研究方法与本章小结
  5. 2020蓝桥杯省赛---java---B---5( REPEAT 程序)
  6. 开源巨头 SUSE 收购 Rancher Labs,云原生时代来临
  7. crontab 周日_linux之crontab命令
  8. Win10下Tensorflow(GPU版)安装趟坑实录,成功了。
  9. 2022春节档新片预售总票房达1.08亿
  10. 【java】java 随机数 Random ThreadLocalRandom SecureRandom
  11. C语言1013山东理工大学试题,山东理工大学史上最全C语言PPTC程序设计(2基本数据与运算).ppt...
  12. ld: library not found for -lcrt1.3.1.o
  13. python 内置变量
  14. html优化布局什么意思,HTML标签布局对seo的重要性(如:h1,p,alt等标签)
  15. 软件测试简历上实战项目:开源项目部署--litemall商城
  16. 液晶显示器测试软件6,屏幕坏点检测工具(Datum pixel repair)
  17. python画正态分布_用python的matplotlib画标准正态曲线
  18. Elastic Sketch: Adaptive and Fast Network-wide Measurements
  19. 对抖音App评论进行抓取
  20. strstr函数的学习

热门文章

  1. 基于Mutisim的数字时钟设计
  2. tornado中文手册
  3. 沉降预测算法-星野法
  4. mockmvc技术分享
  5. Uniapp引用阿里图库
  6. 如何查询数据库存储过程
  7. 儿子想去上海迪斯尼乐园
  8. 简历照片底色要求是什么?怎么修改证件照底色?
  9. 值得深读的书《寿命是自己一点一滴努力来的》(转)
  10. B站(哔哩哔哩)用户画像分析