/* 这种题目一看就知道可以用partition算法做。。。 和上面一题几乎一样的的 再敲一遍代码把 这种方法的弊端是 要改变原来的数组 还有一种O(nlogk) 的算法 就是维护一个最大堆 这牙膏不改变原来数组 但是堆。现在让我写 我已经写不出来了 就用有限队列就可以 还可以用红黑数RBtree stl的set map 都是用红黑树的 rbtree就是通过把节点分为红色和黑色两种颜色 然后一定的规则。。保证一定程度的树平衡 可以用set multiset */ #include<iostream> #include<cstdio> #include<queue> #include<cstdlib> using namespace std; int RandInRange(int a,int b) { return rand()%(b-a)+a; } void Swap(int & a,int &b) { int tmp=a; a=b; b=tmp; } int Partition(int * arr,int len,int start,int end) { int index=RandInRange(start,end); int small=start-1; swap(arr[index],arr[end]); for(index=start;index<end;++index) { if(arr[index]<arr[end]) { small++; if(small!=index) { swap(arr[small],arr[index]); } } } ++small; swap(arr[small],arr[index]); return small; } /* O(n)的算法 但是要改变原来的数组 */ void FindKMinNum(int * arr,int len,int k) { int start=0; int end=len-1; int index=Partition(arr,len,start,end); while(index!=k) { if(index>k) { end=index-1; index=Partition(arr,len,start,end); } else { start=index+1; index=Partition(arr,len,start,end); } } for(int i=0;i<k;++i) { printf("%d ",arr[i]); } printf("\n"); } /* priority_queue就是最大堆。 */ void FindKMinNum_2(int * arr,int len,int k) { priority_queue<int> pq; if(k>len) k=len; for(int i=0;i<k;++i) pq.push(arr[i]); for(int i=k;i<len;++i) { if(arr[i]<pq.top()) { pq.pop(); pq.push(arr[i]); } } while(!pq.empty()) { printf("%d ",pq.top()); pq.pop(); } printf("\n"); } int main() { int arr[]={4,5,1,6,2,7,3,8}; int len=sizeof arr/sizeof *arr; int k=4; FindKMinNum(arr,len,k); FindKMinNum_2(arr,len,k); return 0; }
剑指offer面试题30最小的k个数
最新推荐文章于 2022-09-24 18:11:04 发布