电话面试题--查找数组中第K大的元素

来源:互联网 发布:php在线留言实例 编辑:程序博客网 时间:2024/04/30 07:30

查找数组中第K大的元素。

题目最简单做法就是先进行按元素大小递减的快速排序,然后遍历数组走到K下标即为题目所要求。但是这个需要耗费时间是快排O(nlogn)再加上遍历数组到第K个位置。

这样的时间复杂度肯定面试官难以满意。换个思维假如我对整个数组进行堆排序发现其实时间任然是O(nlogn)和快排基本没提高,但是朝着堆的方向是对的了只是建堆时我们只需要对数组K个元素建堆,然后遍历从K+1开始到最后元素,每次对堆顶元素进行比较维护这个K个元素的最小堆,最终堆顶元素即为我们要找的第K大元素。时间复杂度为O(nlogK)。

代码实现:

#include <iostream>using namespace std;int leftPlace(int i){return 2*i;}int rightPlace(int i){return 2*i+1;}void swap(int &a,int &b){int temp=a;a=b;b=temp;}void MIN_HEAPIFY(int *A,int i,int heap_size){int left,right,min;left=leftPlace(i);right=rightPlace(i);if (left>heap_size){return;}if (left<= heap_size&& A[left]<A[i]){min=left;}else{min=i;}if (right<=heap_size&&A[right]<A[min]){min=right;}if (min!=i){swap(A[i],A[min]);MIN_HEAPIFY(A,min,heap_size);}else{i++;MIN_HEAPIFY(A,i,heap_size);}}void build_MIN_HEAP(int *A,int len){for (int i=len/2;i>=1;i--){MIN_HEAPIFY(A,i,len);}}void Print_HEAPED_ARRAY(int *A,int len){cout<<"建堆后的数组为:\n";for (int i=1;i<=len;i++){cout<<A[i]<<" ";}cout<<endl;}void findKthelement(int *A,int k,int len){for (int i=k+1;i<=len;i++){if (A[i]>A[1]){swap(A[i],A[1]);MIN_HEAPIFY(A,1,k);}}}int main(){cout<<"input K number and ArraySize"<<endl;int K,ArraySize;cin>>K>>ArraySize;int *A=new int[ArraySize+1];//数组结点从i=1下标开始存方便计算左右子结点for (int i=1;i<=ArraySize;i++){cin>>A[i];}build_MIN_HEAP(A,K);Print_HEAPED_ARRAY(A,K);findKthelement(A,K,ArraySize);cout<<"the Kth element \n";cout<<A[1]<<endl;}


 

0 0
原创粉丝点击