概述
题目描述:在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
这是一道排序问题?显然当数组元素N很大时,采用一般O(N^2)的排序算法(如冒泡排序)一定会超时。
所以这里可以使用快排和堆排。这里快排和堆排的思想就不详细介绍了,有兴趣的可以去看我的其他文章或者直接baidu一下。
1.直接快速排序,对整个数组进行排序(156ms)
lass Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
quick_sort(nums, 0, nums.size() - 1);
return nums[nums.size() - k];
}
void quick_sort(vector<int>& nums, int l, int r){
if(l < r){
int pivot = partition(nums, l, r);
quick_sort(nums, l, pivot - 1);
quick_sort(nums, pivot + 1, r);
}
}
int partition(vector<int>& nums, int l, int r){
int p = nums[l];//i的位置已经记录下来
int i = l, j = r;
while(i < j){
//先将大的往后移动
while(i < j && nums[j] >= p){
j --;
}
nums[i] = nums[j];//右边第一个比p小的数
while(i < j && nums[i] <= p){
i ++;
}
nums[j] = nums[i];//左边第一个比p大的数
}
nums[i] = p;
return i;
}
};
2.题目要求是找到第K个大的数即可,所以在quick_sort()函数中,每次partition返回的pivot的索引值和K进行比较,就可以每次减少一部分的排序:(52ms)
int quick_sort(vector<int>& nums, int l, int r, int k){
if(l == r) return nums[l];
int pivot = partition(nums, l, r);
if(pivot == nums.size() - k){
return nums[pivot];
}
else if(pivot > nums.size() - k){//比目标值大,在左边
return quick_sort(nums, l, pivot - 1, k);
}
else{
return quick_sort(nums, pivot + 1, r, k);
}
}
3.在快排中,选择pivot对于整体速度影响很大,所以这里可以采用随机选择index的方法。在partition()中加入以下代码:(16ms)
srand(time(NULL));//随机种子
int r_pos = rand() % (r - l + 1) + l;
swap(nums[l], nums[r_pos]);
4.堆排序
建(大顶)堆-调整-堆排序(“取出前k个大的数即可”)
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
return buildHeap(nums, k);
}
int buildHeap(vector<int>& nums, int k){
//建成一个大顶堆
int n = nums.size();
for(int i = n / 2; i >= 0; -- i){
downAdjust(nums, i, n);
}
for(int j = 0; j < k; j ++){
swap(nums[0], nums[n - 1 - j]);
downAdjust(nums, 0, n - 1 - j);
//堆排序,将最大的,第二大的...,第k大的依次“取出”
}
return nums[n - k];
}
void downAdjust(vector<int>& nums, int i, int n){
//left & right child-node 2*i + 1 / 2*i + 2
int l = 2 * i + 1;
int r = 2 * i + 2;
int maxidx = i;
if(l < n && nums[l] > nums[maxidx]){
maxidx = l;
}
if(r < n && nums[r] > nums[maxidx]){
maxidx = r;
}
if(maxidx != i){
swap(nums[i], nums[maxidx]);//maxidx位置和原i位置交换
downAdjust(nums, maxidx, n);
}
}
};
以上就是这篇的主要内容,如有问题或疑惑,请您指出。谢谢!
最后
以上就是淡定小蘑菇为你收集整理的数组中第K大(小)的元素的全部内容,希望文章能够帮你解决数组中第K大(小)的元素所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复