原题目
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.
For example,
Given [3,2,1,5,6,4] and k = 2, return 5.
中文大意
给定一个无序数组以及一个整数k,求出这个数组中第K大的数
题解1:STL sort(O(nlogn))
对于这道题而言,用STL自带的高效的排序算法,将数组中的元素从大到小排好,然后再从中取出第k个,就是所求。基于比较的排序,时间复杂度
class Solution {
public:
static bool comp(const int &a,const int &b)
{
return a>b;
}
int findKthLargest(vector<int>& nums, int k) {
int n = nums.size();
sort(nums.begin(),nums.end(),comp);
return nums[k-1];
}
};
题解2:利用快速排序(O(n))
在快速排序(本题默认从大到小排序)中,每次递归都涉及到主元的选取,以及划分的操作——小于这个主元的元素都在主元的右边,大于主元的元素都在左边,然后根据主元的位置判断递归哪一段:
- 主元是否就是第K个数
- 主元的位置比K大,说明K在主元的左边,递归左边
- 主元的位置比K小,说明K在主元的右边,递归右边
这样做的话,算法复杂度的期望值是O(n)
class Solution {
public:
int partition(vector<int>& nums,int low, int high)
{
int i = low, j = high, x = nums[low];
while (i < j)
{
while(i < j && nums[j]< x) // 从右向左找第一个大于x的数
j--;
if(i < j)
nums[i++] = nums[j];
while(i < j && nums[i]>= x) // 从左向右找第一个小于等于x的数
i++;
if(i < j)
nums[j--] = nums[i];
}
nums[i] = x;
return i;
}
void quickSort(vector<int>& nums,int low, int high,int k)
{
int mid;
if(low < high)
{
mid = partition(nums,low,high);
if(mid == k-1) return;
else if(mid > k-1) quickSort(nums,low,mid-1,k);
else quickSort(nums,mid+1,high,k);
}
}
int findKthLargest(vector<int>& nums, int k) {
int n = nums.size();
quickSort(nums,0,n-1,k);
return nums[k-1];
}
};
题解3:桶排序(O(n))
桶排序实际上就是记录数组中的每一个数字出现的次数,然后从小到大遍历,看找第k大的数落在哪一个数上。这样做的时间复杂度固定为O(n),但空间复杂度很大(因为要开辟一个很大的数组,如果数组中的数字取值范围很大)。对于空间复杂度的问题,我用了STL中的map来解决,这样算法的空间复杂度也不大。
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
map<int,int> m;
int ans;
int n = nums.size();
for(int i = 0; i<nums.size(); i ++)
{
if(!m.count(nums[i]))
m[nums[i]] = 1;
else
m[nums[i]]++;
}
int total = 0;
map<int,int>::iterator it ;
for(it= m.begin();it != m.end();it++)
{
if(total+it->second > n-k)
{
ans = it->first;
break;
}
else
total += it->second;
}
return ans;
}
};