mirror of
https://github.com/ShusenTang/LeetCode.git
synced 2024-09-02 14:20:01 +00:00
Update 215. Kth Largest Element in an Array.md
This commit is contained in:
parent
ebf28cf557
commit
1c3d9b07bf
@ -3,9 +3,7 @@
|
||||
# 思路
|
||||
给定一个数组, 要求返回其中第k大的数. 这应该属于常考的面试题了, 务必掌握. 有两个基本的思路: 快排划分的思想和最大(小)堆.
|
||||
|
||||
时间复杂度平均为O(n)
|
||||
|
||||
## 思路一
|
||||
## 思路一、快排划分
|
||||
我们回忆一下快排中的partition函数:
|
||||
每次先(任意)确定一个中枢值pivot,然后遍历其他所有的数字,像这道题从大往小排的话,就把大于中枢点的数字放到左半边,
|
||||
把小于中枢点的放在右半边,这样中枢点是整个数组中第几大的数字就确定了,虽然左右两部分各自不一定是完全有序的.
|
||||
@ -15,13 +13,26 @@
|
||||
* 若得到的pos比k-1小, 那在pos右边继续调用partition;
|
||||
* 否则, 在pos左边继续调用partition.
|
||||
|
||||
其实STL中`nth_element`已经帮我们实现了上述过程, 注意学习使用.
|
||||
其实STL中`nth_element`已经帮我们实现了上述过程, 注意学习使用:
|
||||
``` C++
|
||||
nth_element(vc.begin(), vc.begin()+5, vc.end(), cmp); // 没有返回值
|
||||
```
|
||||
**`nth_element`只保证第n(从0开始)个元素是位于最终排序位置的, 但其左右两边的元素则不一定有序.**
|
||||
|
||||
时间复杂度平均O(n)(最坏O(n^2)),空间复杂度O(1)
|
||||
|
||||
> 可以先将nums顺序随机打乱,这样就不会出现最坏时间复杂度的情况。
|
||||
|
||||
|
||||
## 思路二、堆
|
||||
用最小堆, 维护一个大小为k的最小堆(实际不是堆是个二叉树),新来一个元素后如果大小超过了k就去掉top元素(是最小的)即可, 到最后堆里就是最大的k个数,堆顶为第k大的数。
|
||||
|
||||
由于堆大小为k,**初始建堆时间复杂度是线性的**即O(k),后面删除堆顶元素和插入新元素时间都是O(logk),所以总的时间复杂度是O(nlogk);空间复杂度O(k)
|
||||
|
||||
> 也可以用最大堆,用最大堆的话需要将所有元素都进堆,然后再删除堆顶的元素 k-1 次。
|
||||
初始建堆复杂度O(n),再加上 k-1 次删除操作,所以总的时间复杂度为O(n + klogn);堆大小为n,所以空间复杂度O(n)。
|
||||
**所以但当n很大时是用最大堆不合理的,将消耗大量空间。**
|
||||
|
||||
## 思路二
|
||||
用最小堆, 最小堆(实际不是堆是个二叉树)始终保持最小元素在树顶, 那么我们不断去掉top元素知道只剩下k个元素, 那剩下的top元素即所求.
|
||||
> 或者用最大堆, 这样我们不断去掉k-1个最大堆树顶元素后第k大的元素就位于树顶了.
|
||||
|
||||
在STL中, `priority_queue`和`multiset`都可用来作为最小(大)堆, 代码以前者为例, 用`multiset`可以参考[此处](https://leetcode.com/problems/kth-largest-element-in-an-array/discuss/60309/C%2B%2B-STL-partition-and-heapsort)
|
||||
|
||||
@ -33,6 +44,11 @@
|
||||
> 建议详读[讨论区总结](https://leetcode.com/problems/kth-largest-element-in-an-array/discuss/60309/C%2B%2B-STL-partition-and-heapsort)
|
||||
|
||||
|
||||
## 思路三、桶排序
|
||||
|
||||
如果数组里的元素的范围是固定的(有限的),还可以用桶排序。
|
||||
|
||||
|
||||
# C++
|
||||
## 思路一
|
||||
``` C++
|
||||
|
Loading…
Reference in New Issue
Block a user