题目描述

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例 1:

输入: [3,2,1,5,6,4] 和 k = 2

输出: 5

示例 2:

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4

输出: 4

说明:

你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。

题解

根据问题的描述其实我们很容易想到先排序再取第k个值, 这种方式也就是我们俗称的暴力求解法。

暴力求解法

思路分析:

数组排序后的第k个最大元素,举例说明一下:

数组一共有5个元素时,找第2大,索引值是3;找第4大,索引值是1;根据这个逻辑我们可以推导出,数组升序排序以后,结果元素的索引值是数组长度减去k的值

代码示例:

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

复杂度分析:

  • 时间复杂度:O(N log N), 这里直接使用Arrays.sort(nums);将数据排序,大家都知道jdk默认使用的是快速排序,快速排序的平均时间复杂度是O(N log N)
  • 空间复杂度:O(1),因为是原地排序,没有用到外部辅助空间。

暴力求解法(升级版)

思路分析:

根据暴力求解法中用的快排思路,其实我可以对快排做近一步升级,首先我们随机选择一个元素,并在线性时间内找到其对应在数组中的位置,这样数组就被分成了两部分,一部分是小于元素值的部分,一部分是大于元素值的部分,这时我们在比较这个元素与k的大小来决定我们在那一部分数组继续做快速排序。这种思路其实就是快速排序中partition(切分)的操作。

每次partition操作总能排定一个元素,还能够知道这个元素它在数组中的最终位置,然后我们在根据partition后的结果来减少范围,这样的思想叫做“减而治之”。

代码示例:

public static int findKthLargest(int[] nums, int k) {
int leng = nums.length;
int left = 0;
int right = leng - 1;
int target = leng - k;
return quickSelect(nums, left, right, target);
} /**
* 排序
* @param nums
* @param left
* @param right
* @param target
* @return
*/
public static int quickSelect(int[] nums, int left, int right, int target) {
if (left == right) {
return nums[left];
}
//随机选择一个
Random random = new Random();
int pivot = left + random.nextInt(right - left); pivot = partition(nums, left, right, pivot);
if (target == pivot) {
return nums[target];
}
if (target < pivot) {
return quickSelect(nums, left, pivot - 1, target);
}
return quickSelect(nums, pivot + 1, right, target);
} /**
* partition切分
* @param nums
* @param left
* @param right
* @param target
* @return
*/
private static int partition(int[] nums, int left, int right, int target) {
int pivot = nums[target];
swap(nums, target, right);
int j = left;
for (int i = left; i <= right; i++) {
if (nums[i] < pivot) {
swap(nums, j, i);
j++;
}
}
swap(nums, j, right);
return j;
} /**
* 交换
* @param nums
* @param a
* @param b
*/
public static void swap(int[] nums, int a, int b) {
int temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
}

复杂度分析:

  • 时间复杂度:平均情况O(N), 最坏情况O($N^2$).
  • 空间复杂度:O(1).

  • 写作不易,转载请注明出处,喜欢的小伙伴可以关注公众号查看更多喜欢的文章。
  • 联系方式:4272231@163.com
  • QQ:95472323
  • 微信:ffj2000

【一起刷LeetCode】在未排序的数组中找到第 k 个最大的元素的更多相关文章

  1. 在未排序的数组中找到第 k 个最大的元素

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

  2. leetcode.排序.215数组中的第k个最大元素-Java

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

  3. [程序员代码面试指南]第9章-在两个长度相等的排序数组中找到第k小的数(二分)

    题目 给定两个有序数组arr1和arr2,再给定一个整数k,返回所有的数中第k小的数. 题解 利用题目"在两个长度相等的排序数组中找到第上中位数"的函数 分类讨论 k < 1 ...

  4. 算法总结之 在两个排序数组中找到第K小的数

    给定两个有序数组arr1 和 arr2 ,再给定一个int K,返回所有的数中第K小的数 要求长度如果分别为 N M,时间复杂度O(log(min{M,N}),额外空间复杂度O(1) 解决此题的方法跟 ...

  5. LeetCode题解 | 215. 数组中的第K个最大元素

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

  6. LeetCode:数组中的第K个最大元素【215】

    LeetCode:数组中的第K个最大元素[215] 题目描述 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: ...

  7. [LeetCode]215. 数组中的第K个最大元素(堆)

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

  8. 数组中的第K个最大元素leetcode(Top K的问题)

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

  9. Leetcode 215. 数组中的第K个最大元素 By Python

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

随机推荐

  1. 了解web漏洞-sql注入

    1:为什么要学web漏洞? 作为一个运维人员,日常工作就是保障服务器和网站的业务正常运行,平时也需要对服务器的安全工作加固,说到防护攻击问题,那么久必须去了解攻击者是怎么对服务器发动的一个流程,这样才 ...

  2. 【CentOS7】设置静态IP地址

    [CentOS7]设置静态IP地址 转载:https://www.cnblogs.com/yangchongxing/p/10645871.html 图像化修改 nmtui 查看当前网卡名称 # if ...

  3. .net下DllImport的一个小问题

    最近搞几个PInvoke几个DLL, 在.net 2.0下木有问题, 跑的很好 如下: [DllImport( "tjo.dll" )] private static extern ...

  4. JSP注册登录页教程

    转载请标明原文地址:http://www.cnblogs.com/zhangyukof/p/6785258.html  一.准备工作 已搭建好的SSH框架工程一个,如果没有,请参考我的上一篇文章< ...

  5. Python之如何修改运行的快捷键

    如果你在Pycharm中运行程序使用Ctrl+shift+F10快捷键,运行失败,使用Pycharm工具组,右键一下选择“Run+文件名称AAA”运行程序,直接运行成功的话,那么你就可以 更换自己的运 ...

  6. 解压小游戏之打砖块(C#+unity)

    z这个小游戏很简洁,很简单,非常适合一个人玩,特别减压

  7. springboot启动原理解析

    springboot核心原理: 1.基于springmvc无配置文件完全注解化 + 内置web容器实现springboot框架.main函数方式的启动 2.通过maven快速整合第三方框架 sprin ...

  8. dotnetcore执行shell脚本

    我们可以使有dotnetcore跨平台的特性,优雅的实现在dotnetcore执行shell (bash).  代码如下: using System; using System.Collections ...

  9. Tomcat系列(二)- EndPoint源码解析

    在上一节中我们描述了Tomcat的整体架构, 我们知道了Tomcat分为两个大组件,一个连接器和一个容器. 而我们这次要讲的 EndPoint的组件就是属于连接器里面的. 它是一个通信的端点,就是负责 ...

  10. 松软科技Web课堂:JavaScript Break 和 Continue

    break 语句“跳出”循环. continue 语句“跳过”循环中的一个迭代. Break 语句 在本教程稍早的章节中,您已见到了 break 语句.它被用于“跳出” switch 语句. brea ...