215. 数组中的第K个最大元素
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
分析
先将数组从小到大排好序,你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。尽量采用o(nlogn)复杂度的排序算法,取数组中序号为nums.size()-k的数即为第k个最大的数。代码需要天天练习,继续刚
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
// quicks(nums,0,nums.size());
// solve(nums,0,nums.size()-1);
// for(int i=nums.size()/2-1;i>=0;--i){
// dui(nums,i);
// }
for(int i=nums.size()/2-1;i>=0;--i)
dui(nums,i,nums.size());
for(int i=nums.size()-1;i>0;--i){
int temp= nums[0];
nums[0] = nums[i];
nums[i] = temp;
dui(nums,0,i);
}
return nums[nums.size()-k];
}
// 新加入节点i 大根堆
void dui(vector<int>&nums,int i,int len){
// len代表在[0,len)上满足大根堆
int temp= nums[i];
// 保存要调整的值,等会儿要交换
// k先设置为i的左儿子
for(int k=2*i+1;k<len;k=2*k+1 ){
if(k+1<len&&nums[k]<nums[k+1]){
// k保存i的两个儿子中大的节点的序号
k++;
}
if(temp<nums[k]){
nums[i] = nums[k];
i=k;
}
else break;
}
nums[i] = temp;
}
// // 新加入节点i 大根堆
// void dui(vector<int>&nums,int i,int len){
// // len代表在[0,len]上满足大根堆
// int temp= nums[i];
// // 保存要调整的值,等会儿要交换
// // k先设置为i的左儿子
// for(int k=2*i+1;k<=len;k=2*k+1 ){
// if(k+1<=len&&nums[k]<nums[k+1]){
// // k保存i的两个儿子中大的节点的序号
// k++;
// }
// if(temp<nums[k]){
// nums[i] = nums[k];
// i=k;
// }
// else break;
// }
// nums[i] = temp;
// }
// 归并排序 将a[first,mid] a[mid+1,last] 合并
// void mergearray(vector<int>&a,int first,int mid,int end){
// vector<int>temp(end+1);
// int i=first,k=mid+1;
// // 两个待合并数组的起点
// int p=0;
// // 小的先放在临时数组里面
// while(i<=mid&&k<=end){
// if(a[i]<a[k]){
// temp[p] = a[i];
// p++,i++;
// }
// else if(a[i]>=a[k]){
// temp[p] = a[k];
// p++,k++;
// }
// }
// // 把剩余部分依次放到临时数组里面
// while(i<=mid){
// temp[p] = a[i];
// p++,i++;
// }
// while(k<=end){
// temp[p] = a[k];
// p++,k++;
// }
// // 把临时数组里面已经有序的元素拷贝回来
// for(int j=0;j<p;++j){
// a[first+j] = temp[j];
// }
// temp.clear();
// }
// void solve(vector<int>&nums,int first,int last){
// // 排序区间是【】 first==last时不用排序
// if(first<last){
// int mid = (first+last)/2;
// // 左边有序
// solve(nums,first,mid);
// // 右边有序
// solve(nums,mid+1,last);
// // 合并
// mergearray(nums,first,mid,last);
// }
// }
// 快速排序
// void quicks(vector<int>&nums,int start,int end ){
// // 排序区间为[start,end)
// if(start<end){
// int i = start;
// int j = end-1;
// int flag = nums[start];
// // 取枢纽值,比较标准值
// while(i<j){
// // 从右往左找比flag小的数,保存到nums[i]中
// while(nums[j]>=flag&&i<j) j--;
// nums[i] = nums[j];
// // 从左往右找比flag大的数,保存到num[j]中
// while(nums[i]<flag&&i<j) i++;
// nums[j] = nums[i];
// }
// nums[i] = flag;
// quicks(nums,start,i);
// quicks(nums,i+1,end);
// }
// }
// void quicks(vector<int>&nums,int fir,int end){
// int i=fir,j=end;
// int x = nums[i];
// if(fir>=end) return ;
// // int temp;
// while(i<j){
// while(nums[j]>=x&&i<j) j--;
// nums[i] = nums[j];
// while(nums[i]<=x&&i<j) i++;
// nums[j] = nums[i];
// }
// nums[i] = x;
// if(fir<i)
// quicks(nums,fir,i-1);
// if(i<end)
// quicks(nums,i+1,end);
// }
};