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

问题描述

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

示例 1:

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

示例 2:

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

说明:

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

快排

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Solution {
private:
void sort(vector<int>& nums, int l, int h) {
if (l >= h) return;
int j = partition(nums, l, h);
sort(nums, l, j-1);
sort(nums, j+1, h);
}
int partition(vector<int>& nums, int l, int h) {
int v = nums[l];
int i = l;
int j = h + 1;
while (true) {
while (nums[++i] > v) if (i >= h) break;
while (nums[--j] < v) if (j <= l) break;
if (i >= j) break;
exch(nums, i, j);
}
exch(nums, l, j);
return j;
}
void exch(vector<int>& nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
public:
int findKthLargest(vector<int>& nums, int k) {
random_shuffle(nums.begin(), nums.end()); // 打乱顺序
sort(nums, 0, nums.size()-1);
return nums[k-1];
}
};

排序 :时间复杂度 O(nlogn),空间复杂度 O(1)

最小堆

创建一个小顶堆,将所有数组中的元素加入堆中,并保持堆的大小小于等于 k。这样堆中就保留了前 k 个最大的元素。堆顶的元素就是第k大元素。

下面使用堆的写法,修改了输入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
make_heap(nums.begin(), nums.end());
while(--k > 0) { // // k
pop_heap(nums.begin(), nums.end()); // logn
nums.pop_back();
}
// for (int i = 0; i < nums.size(); ++i) {
// printf("nums[%d]=%d\n", i, nums[i]);
// }
return nums[0];
}
};

O(klogn) 时间, O(n) 空间

使用优先队列写法:

1
2
3
4
5
6
7
8
9
10
11
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int, vector<int>, greater<int>> min_heap;
for (int i = 0; i < nums.size(); ++i) { // n
min_heap.push(nums[i]); // logk
if (min_heap.size() > k) min_heap.pop();
}
return min_heap.top();
}
};

O(nlogk) 时间, O(k) 空间

虽然理论上当k<n时,最小堆比使用快排快,但在LeetCode上测试多次均是快排快。优先队列是对堆的包装,某些场合下比堆好用。

------ 本文结束------
赞赏此文?求鼓励,求支持!
  • 本文标题: 【LeetCode】215 数组中的第K个最大元素
  • 本文作者: Jiang.G.F
  • 创建于: 2020年01月15日 - 23时01分
  • 更新于: 2020年03月03日 - 11时03分
  • 本文链接: https://gfjiangly.github.io/leetcode/leetcode_215.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
0%