描述
在数组中找到第k大的元素
你可以交换数组中的元素的位置
您在真实的面试中是否遇到过这个题? 是
样例
给出数组 [9,3,2,4,8]
,第三大的元素是 4
给出数组 [1,2,3,4,5]
,第一大的元素是 5
,第二大的元素是 4
,第三大的元素是 3
,以此类推
挑战
要求时间复杂度为O(n),空间复杂度为O(1)
分析:
1、可以使用快排,但不符合时间复杂度要求
2、使用中位数——parition()方法,还是基于快排,但做了改进,符合时间复杂度O(n)
思想:
partition函数:先找到一个基数,使比它大的都在它左边,比它小的都在它优右边,两边可以无序,最后返回这个基数的位置
然后比较这个基数的位置与n-1的大小,如果等于n-1,则这个数就是第k大的数
否则,如果基数位置小于n-1,则在其右半部分找
如果基数位置大于n-1,则在其左半部分找
代码:
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
int left = 0, right = nums.size() - 1;
while (true) {
int pos = partition(nums, left, right);
if (pos == n - 1)
return nums[pos];
else if (pos > n - 1)
right = pos - 1;
else left = pos + 1;
}
}
int partition(vector<int>&nums,int l,int r)
{
int i=l,x=nums[l];
int j=r;
while(i<j)
{
while(i<j&&nums[j]<x)
j--;
if(i<j)
nums[i++]=nums[j];
while(i<j&&nums[i]>=x)
i++;
if(i<j)
nums[j--]=nums[i];
}
nums[i]=x;
return i;
}
};