問題描述:
在未排序的數組中找到第K個最大的元素。請注意,你需要找的是數組排序後的第K個最大元素,而不是第K個不同的元素。
、問題分析:
這裏我們給出三種典型的解法:
【1】使用庫函數的方法:sort()
class Solution{
public:
int findKthLargest(vector<int>& nums, int k)
{
sort(nums.begin(),nums.end());
return nums[nums.size()-k];
}
};
【2】使用快速排序算法:
快速排序的基本思想是:找一個基準,把所有小於基準的數放在左邊,大於基準的數全部放在右邊,完成一個基準點位置後,基準這個地方的值是不會改變的。按照快速排序的思想,我們對基準的左右兩邊進行遞歸,實現快排。
class Solution{
public:
int findKthLargest(vector<int>& nums, int k){
int low =0, high = nums.size()-1, mid =0;
while(low<=high)
{
mid = partition(nums,low,high);
if(mid ==k-1) return nums[k-1];
else if(mid>k-1) high = mid-1;
else low = mid+1;
}
return -1; //表示出現錯誤,沒有找到第K大的數,這裏不存在
}
int partition(vector<int>& nums, int low, int high)
{
int left = low+1, right = high;
swap(nums[low],nums[(low+high)/2]);
int povit = nums[low];
//採用雙指針,快速排序,交換不符合條件的數據
while(left<=right)
{
while(left<high && nums[left]>=povit) left++;
while(nums[right]<povit) right--;
if(left<right) swap(nums[left++],nums[right--]);
else break;
}
swap(nums[low],nums[right]);
return right;
}
};
【3】採用堆排序算法(或者說是最小頂堆的辦法):找出維持K個最大數的堆,其中最小的那個數就是解。
首先需要介紹一下最小頂堆的方式。引入一個優先隊列的數據結構:
就是說q這個隊列裏面的元素都是按升序排列好的(隊頭是最小的)
那麼我們只需要不停的把元素放入優先隊列
它會自動排序
然後穩定好隊列的長度爲k即可
如果長度超過k了,那就出隊隊頭,即隊列中最小的元素
最後返回隊列的隊頭,即爲第k大的元素
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
//升序的優先隊列
priority_queue <int,vector<int>,greater<int> > ascending; //是一個升序優先隊列
for (int &i:nums)
{
ascending.push(i);
if (ascending.size()>k)
ascending.pop();
}
return ascending.top();
}
};