题目:215. 数组中的第K个最大元素
在未排序的数组中找到第 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 ≤ 数组的长度。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
基本思想1:快速排序
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
//快排的思想
k = nums.size() - k;//相当于寻找排在第k个位置的元素
//1,2,3,4,5,6
return fun(nums, 0, nums.size() - 1, k);
}
int fun(vector<int>& nums, int l, int r, int k){
int pos = quick_sort(nums, l, r);
if(pos == k)
return nums[k];
else if(pos > k){
return fun(nums, l, pos - 1, k);
}
else{
return fun(nums, pos + 1, r, k);
}
}
int quick_sort(vector<int>& nums, int left, int right){
int flag = nums[left];
int i = left, j = right;
while(i < j){
while(i < j && nums[j] >= flag)
--j;
if(i < j)
nums[i] = nums[j];
while(i < j && nums[i] < flag)
++i;
if(i < j)
nums[j] = nums[i];
}
nums[i] = flag;
return i;
}
};
基本思想2:堆排序
- 核心代码是:调整堆,指示要调整的位置,从该位置往下调整
- 首先,借助调整堆的函数构建初始堆,从堆的最后一个非叶子节点开始依次递减调整
- 然后,依次将未排序的元素放在0号位置开始调整
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
//堆排,大根堆
k = nums.size() - k;
heap_sort(nums, k);
return nums[k];
}
void swap(int &a, int &b){
int temp = a;
a = b;
b = temp;
}
void heap_sort(vector<int>& nums, int k){
for(int i = nums.size() / 2 - 1; i >= 0; --i){//注意该循环的变量i
adjust_heap(nums, i, nums.size());
}
for(int i = nums.size() - 1; i >= k; --i){
swap(nums[0], nums[i]);
adjust_heap(nums, 0, i);
}
}
void adjust_heap(vector<int>& nums, int i, int l){
for(int k = 2 * i + 1; k < l; k = 2 * k + 1){//注意该循环的变量k
if(k + 1 < l && nums[k] < nums[k + 1])
++k;
if(nums[i] < nums[k]){
swap(nums[i], nums[k]);
i = k;
}
else
break;
}
}
};
基本思想3:借助优先队列
大根堆,申请数组长度个空间
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int> pq(nums.begin(), nums.end());
int res;
while(k--){
res = pq.top();
pq.pop();
}
return res;
}
};
小根堆,申请k个空间
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int, vector<int>, greater<int>> pq;
int res;
int i = 0;
while(k--){
pq.push(nums[i++]);
}
while(i < nums.size()){
if(nums[i] > pq.top()){
pq.pop();
pq.push(nums[i]);
}
++i;
}
return pq.top();
}
};