題目描述
- 題目
在未排序的數組中找到第 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();
}
};