描述
有一个整数数组,请你根据快速排序的思路,找出数组中第 k 大的数。
给定一个整数数组 a ,同时给定它的大小n和要找的 k ,请返回第 k 大的数(包括重复的元素,不用去重),保证答案存在。
要求:时间复杂度 O(nlogn)O(nlogn),空间复杂度 O(1)O(1)
示例1
输入:
[1,3,5,2,2],5,3返回值:
2
示例2
输入:
[10,10,9,9,8,7,5,6,4,3,4,2],12,3返回值:
9说明:去重后的第3大是8,但本题要求包含重复的元素,不用去重,所以输出9
快速排序:C++
vector<int>quickSort(vector<int>& nums, int start, int end) {
if (start >= end)return nums;
int base = nums[start];
int i = start;
int j = end;
while (i < j) {
while (i < j && nums[j] >= base)
j--;
swap(nums[i], nums[j]);
while (i < j && nums[i] <= base)
i++;
swap(nums[i], nums[j]);
}
quickSort(nums, start, i - 1);
quickSort(nums, i + 1, end);
return nums;
}
采用快排思想:base右边元素个数超过K,结果肯定在右边
class Solution {
public:
vector<int> quickSort(vector<int>&nums, int start, int end, int K)
{
if (start >= end) return nums;
int randPos = rand() % (end - start + 1) + start;//随机化寻找base元素,以免时间复杂度退化到 O(N^2)
swap(nums[start], nums[randPos]);
int base = nums[start];
int i = start;
int j = end;
while (i < j)
{
while (i < j && nums[j] >= base) j--; //从右往左,寻找比base小的数
swap(nums[i], nums[j]);
while (i < j && nums[i] <= base) i++;
swap(nums[i], nums[j]);
}
if(nums.size()-i<K) //如果base右边的数超过K个,则第K大数肯定在base右边,此时就不需要对base左边的进行排序
quickSort(nums, start, i - 1, K);
quickSort(nums, i + 1, end, K);
return nums;
}
int findKth(vector<int> a, int n, int K) {
quickSort(a, 0, n-1, K);
return a[n-K];
}
};