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

题目地址(215. 数组中的第K个最大元素)

https://leetcode-cn.com/problems/kth-largest-element-in-an-array/

题目描述


在未排序的数组中找到第 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 ≤ 数组的长度。

前置知识

  • Quick Select

公司

  • 阿里

  • 腾讯

  • 百度

  • 字节

思路

这道题要求在一个无序的数组中,返回第K大的数。根据时间复杂度不同,这题有3种不同的解法。

解法一 (排序)

很直观的解法就是给数组排序,这样求解第K大的数,就等于是从小到大排好序的数组的第(n-K)小的数 (n 是数组的长度)。

例如:

时间复杂度: O(nlogn) - n 是数组长度。

解法二 - 小顶堆(Heap)

可以维护一个大小为K的小顶堆,堆顶是最小元素,当堆的size > K 的时候,删除堆顶元素. 扫描一遍数组,最后堆顶就是第K大的元素。 直接返回。

例如: heap

时间复杂度O(n * logk) , n is array length 空间复杂度O(k)

跟排序相比,以空间换时间。

解法三 - Quick Select

Quick Select 类似快排,选取pivot,把小于pivot的元素都移到pivot之前,这样pivot所在位置就是第pivot index 小的元素。 但是不需要完全给数组排序,只要找到当前pivot的位置是否是在第(n-k)小的位置,如果是,找到第k大的数直接返回。

具体步骤:

quick select

时间复杂度

  • 平均是:O(n)

  • 最坏的情况是:O(n * n)

关键点分析

  1. 直接排序很简单

  2. 堆(Heap)主要是要维护一个K大小的小顶堆,扫描一遍数组,最后堆顶元素即是所求。

  3. Quick Select, 关键是是取pivot,对数组区间做partition,比较pivot的位置,类似二分,取pivot左边或右边继续递归查找。

代码(Java code)

解法一 - 排序

解法二 - Heap (PriorityQueue)

解法三 - Quick Select

参考(References)

最后更新于

这有帮助吗?