题目描述:
在数组中找到第k大的元素
样例
给出数组 [9,3,2,4,8],第三大的元素是 4
给出数组 [1,2,3,4,5],第一大的元素是 5,第二大的元素是 4,第三大的元素是 3,以此类推
挑战
要求时间复杂度为O(n),空间复杂度为O(1)
注意事项
你可以交换数组中的元素的位置
1.使用选择排序进行求解:(此种方法满足不了时间复杂度的要求,算法复杂度为O(N^2))
class Solution {
public:
/**
* @param n: An integer
* @param nums: An array
* @return: the Kth largest element
*/
int kthLargestElement(int n, vector<int> &nums) {
// write your code here
for(int i=0;i<nums.size();i++)
{
int mix=i;
for(int j=i+1;j<nums.size();j++)
{
if(nums[j]<nums[i])
{
mix=j;
}
}
swap(nums[i],nums[mix]);
}
return nums[nums.size()-n];
}
};
2.使用快速排序(代码书写导致复杂度仍然不行,算法复杂度为O(N*k))
class Solution {
public:
/**
* @param n: An integer
* @param nums: An array
* @return: the Kth largest element
*/
int kthLargestElement(int n, vector<int> &nums)
{
n=nums.size()+1-n;
return kMax(n,nums,0,nums.size()-1);
}
int kMax(int n,vector<int> &nums,int left,int right)
{
int index = select(nums,left,right);
if(index==n-1)
return nums[index];
if(index<n-1)
return kMax(n,nums,index+1,right);
else
return kMax(n,nums,left,index-1);
}
int select(vector<int> &nums,int left, int right)
{
if(left==right)
return left;
int biao_zhun=nums[right];
int index=left-1;
for(int i=left;i<right;++i)
{
if(nums[i]<biao_zhun)
{
int temp = nums[i];
nums[i]=nums[++index];
nums[index]=temp;
}
}
nums[right]=nums[++index];
nums[index]=biao_zhun;
return index;
}
};
3、快速排序最终版(时间复杂度满足O(N))
使用partition 标准模板
class Solution {
public:
/**
* @param n: An integer
* @param nums: An array
* @return: the Kth largest element
*/
int kthLargestElement(int n, vector<int> &nums)
{
if (nums.size() == 0 || n < 1 || n > nums.size()) //如果数组长度为0
{
return -1;
}
return partition(nums, 0, nums.size() - 1, nums.size() - n);
}
private:
int partition(vector<int> &nums, int start, int end, int n)
{
if (start >= end)
{
return nums[n];
}
int left = start, right = end;
int pivot = nums[(start + end) / 2];
while (left <= right) {
while (left <= right && nums[left] < pivot)
{
left++;
}
while (left <= right && nums[right] > pivot)
{
right--;
}
if (left <= right)
{
swap(nums, left, right);
left++;
right--;
}
}
if (n <= right)
{
return partition(nums, start, right, n);
}
if (n >= left)
{
return partition(nums, left, end, n);
}
return nums[n];
}
void swap(vector<int> &nums, int i, int j)
{
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
};