
https://leetcode.com/problems/kth-largest-element-in-an-array/
1. 思路
求第k大的数。如果先排序再取第k个数,时间复杂度O(nlogn),太naive
采用快速排序的思路,每次遍历后返回pivot(快速排序中的专有名词)的位置,如果该位置不是k,则对新的更小的数组执行快速排序操作,依次类推,直到pivot的位置是k为止。
时间复杂度分析:
第一遍快排肯定循环了n次,但第二次快排不需要循环n次了,后面循环的次数会越来越小。总体来说时间复杂度是比快速排序要小的,因为每次快排之后只需要对左边或者右边再排序,而不用像传统快速排序那样左边右边再排序一遍。
传统快速排序的时间复杂度为T(N)=T(N/2)*2+cN,求解通项公式为T(N)=cNlog(N)+N=O(NlogN)
那么此题的时间复杂度为T(N)=T(N/2)+cN,通项公式似乎不太好解,而且如果中间哪一步pivot的位置是k了,后面的步骤是不用再跑的,就更快了。总之关于时间复杂度这里还没有很好的解释,只能说是比快排要快的。但是LeetCode的discuss中说这个方法时间复杂度是O(n),如果有能解释的同学欢迎指导,谢谢。
2. 注意的细节
对三个数进行排序,这三行的顺序不能变
if(nums[left]>nums[mid]) swap(nums[left], nums[mid]);
if(nums[left]>nums[right]) swap(nums[left], nums[right]);
if(nums[mid]>nums[right]) swap(nums[right], nums[mid]);
如果数组的长度大于3,就没有必要快排了(也做不了快排),直接返回pivot的位置
if(right-left>=3) mid = quick_sort(nums, left, right);
else mid=(left+right)/2;
求的是第k大的数,但是pivot的位置是从小到大排序的,所以需要转换一下
target=nums.size()-k;
3. AC代码(Runtime: 8 ms, faster than 98.79% of C++ )
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
int left=0, right=nums.size()-1, target=nums.size()-k;
int mid;
while(left < right){
median(nums, left, right);
if(right-left>=3) mid = quick_sort(nums, left, right);
else mid=(left+right)/2;
if(mid > target) right = mid-1;
else if(mid < target) left = mid + 1;
else return nums[mid];
}
return nums[left];
}
void median(vector<int>& nums, int left, int right){
int mid = (left+right)/2;
if(nums[left]>nums[mid]) swap(nums[left], nums[mid]);
if(nums[left]>nums[right]) swap(nums[left], nums[right]);
if(nums[mid]>nums[right]) swap(nums[right], nums[mid]);
swap(nums[mid], nums[right-1]);
}
int quick_sort(vector<int>& nums, int left, int right){
int i = left, j=right-1;
while(i<j){
while(nums[++i]<nums[right-1]){}
while(nums[--j]>nums[right-1]){}
if(i<j) swap(nums[i], nums[j]);
else break;
}
swap(nums[i], nums[right-1]);
return i;
}
};
这篇博客讨论了如何在不完全排序数组中找到第k大的元素,避免使用O(nlogn)的时间复杂度。作者介绍了采用快速排序思想,通过不断调整pivot找到正确位置的方法,虽然具体时间复杂度不易精确计算,但比快速排序更优。同时,注意数组长度大于3时的处理以及结果转换。附带AC代码,运行时间8ms,在C++中表现优秀。
847

被折叠的 条评论
为什么被折叠?



