在未排序的数组中找到第 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 ≤ 数组的长度。
快排解决这个问题。
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
//int romanToInt(char* s) ;
//int rob(int* nums, int numsSize);
int partition(int *nums,int low,int high);//一次快速排序
int findkth(int *nums,int low,int high,int k);
int findKthLargest(int* nums, int numsSize, int k);// 数组中的第K个最大元素
int main()
{
int nums[]={3,2,1,5,6,4};
int ans=findKthLargest(nums,6,2);
printf("%d\n",ans);
return 0;
}
int partition(int *nums,int low,int high){
int temp=nums[low];
while(low<high){
while(low<high&&nums[high]>=temp)
--high;
nums[low]=nums[high];
while(low<high&&nums[low]<=temp)
++low;
nums[high]=nums[low];
}
nums[low]=temp;
return low;
}
int findkth(int* nums,int left,int right,int k){
int loc=partition(nums,left,right);
printf("现在位置在第%d位\n",loc);
if(loc==k) return nums[loc];
else if(loc>k)
return findkth(nums,left,loc-1,k);//k是位置下标别搞错了
else
return findkth(nums,loc+1,right,k);
}
int findKthLargest(int* nums, int numsSize, int k) {
printf("求第%d小的元素\n",numsSize-k);
return findkth(nums,0,numsSize-1,numsSize-k); //注意这个位置的换算
}
堆排序揭发解法,也可以参考:
void swap(int* array,int a,int b){
int tmp=array[a];
array[a]=array[b];
array[b]=tmp;
}
void siftdown(int* array,int k,int i){
int min=array[i];
int index=i;
if(2*i+1<k && array[2*i+1]<min){
min=array[2*i+1];
index=2*i+1;
}
if(2*i+2<k && array[2*i+2]<min){
min=array[2*i+2];
index=2*i+2;
}
if (min == array[i]) return;
swap(array,i,index);
siftdown(array,k,index);
}
int findKthLargest(int* nums, int numsSize, int k) {
int* array=(int*)malloc(sizeof(int)*k);
memcpy(array,nums,sizeof(int)*k);
for(int i=k/2;i>=0;i--) siftdown(array,k,i); //构造一个最小堆
for(int i=k;i<numsSize;i++){
if(nums[i]>array[0]){
array[0]=nums[i];
siftdown(array,k,0);
}
}
return array[0];
}