题目描述
- 题目
在未排序的数组中找到第 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 ≤ 数组的长度。
解题
sort版本
思路
由题意可知,需要返回的是给定数组中第K大的数,则我们可以对数组进行排序(排升序/排降序),这样就可知知道题目中所需要查找的元素在数组中的位置
- 排升序版本:std::sort()默认排升序
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
sort(nums.begin(),nums.end());
return nums[nums.size()-k];
}
};
- 排降序,使用lambda表达式实现
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
sort(nums.begin(),nums.end(),[](int a,int b){return a>b;});
return nums[k-1];
}
};
优先队列版
思路
-
申请一个优先队列用于存储待排序的数组(在插入的同时就会进行排序)
-
此时实现的是大根堆,取K次堆顶元素,记录之后便释放堆顶元素(因为在将堆顶元素弹出之后,堆会继续调整成满足堆性质的状态)
-
堆排序的插入(优先队列底层就是通过堆实现的)
-
可以看到在往堆中插入数据的同时在不断调整堆中的数字,使得其整体符合堆的性质
-
根结点的值比左右子树的结点中的值都大
-
堆排序的弹出
-
在堆的弹出过程中,不断的取走堆顶元素(堆中最大的数).
-
在取走堆顶元素的同时将堆尾元素放到堆顶,并调整结点,使得整体符合堆的性质.
-
维护一个数组大小规模的优先队列
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int> pq;
for(auto& e:nums){
//将数组中所有的数都插入到优先队列中
pq.push(e);
}
int ret=0;
for(int i=0;i<k;i++){
//不断的取走堆顶元素,直到条件结束
ret=pq.top();
pq.pop();
}
return ret;
}
};
- 维护一个k大小的优先队列
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int,vector<int>,greater<int>> q;
for(auto it:nums){
q.push(it);
if(q.size()>k)
//条件限制了堆的规模,在不断的取走堆顶的那个元素
q.pop();
}
return q.top();
}
};