215. Kth Largest Element in an Array 第 K 大的数
215. Kth Largest Element in an Array 第 K 大的数
第一次解法
从大到小排序然后输出 K-1 的元素 时间复杂度: n(logn)
int findKthLargest(vector<int>& nums, int k) {
sort(nums.begin(), nums.end(), greater<int>());
return nums[k-1];
}快速选择
时间复杂度:平均 O(n)
与快排一模一样的 Partition 分割函数,但是分治的依据不同,而且有序的查找我们只需要单边处理即可
int findKthLargest(vector<int>& nums, int k) {
// 找第K大可以转化成找从小到大排序后 len-k 位置的元素
k=nums.size()-k;
int lo=0;
int hi=nums.size()-1;
while(lo<hi) {
int i=partition(nums, lo, hi);
// 前K个的元素都比主元小,找到
if (i==k) {
break;
} else if (i>k) {
// 多于 K 个元素比主元小,目标一定在前半边
hi=i-1;
} else {
// 少于 K 个元素比主元小,那么目标一定在后半边
lo=i+1;
}
}
return nums[k];
}
// 与快排一致的分治排序算法
int partition(vector<int>& nums, int st, int end) {
int pivot=nums[end];
int i=st-1;
for(int j=st;j<end;++j) {
if (nums[j]<pivot) {
++i;
swap(nums[i], nums[j]);
}
}
swap(nums[end], nums[i+1]);
return i+1;
}堆解法 — 适用于海量数据
时间复杂度:nlog(k) 适用于 n 很大而 k 较小的情况
- 使用最大堆,一次性构建然后取 K 次
- 使用最小堆,构建 K 个元素的最小堆,然后容量超过 K 之后判断堆顶元素是否小于插入元素,如果是,则弹出堆顶并插入新元素,一直维护到数据末尾即可
- 使用 set 或者 multiset 这种有序容器,道理类似
#堆