I want to design a function to find the k biggest elements in a unordered set of N elements with time complexity: Θ(N+klogN) on an online judge.
here is a sample:
Input
LN 1 : N K
LN 2 : N numbers
Output
LN 1 : K biggest number
LN 2 : Final heap
Sample Input
10 4
17 19 26 37 30 11 5 29 32 1
Sample Output
29
26 19 11 17 1 5
And here is my code:
#include <iostream>
using namespace std;
int main(){
int i,j,rc,temp,temp1,length,K;
cin>>length>>K;
int *heap = new int[length];
for(i=0;i<length;i++) cin>>heap[i];
for(i=length/2-1;i>=0;i--){ //build a max heap first with Θ(N)
while(!((i>=length/2)&&(i<length))){
j = 2*i+1;
rc = 2*i+2;
if((rc<length)&&(heap[j]<heap[rc])) j=rc;
if(heap[i]>heap[j]) break;
temp = heap[i];
heap[i]=heap[j];
heap[j]=temp;
i=j;
}
}
int k,n=length;
for(k=0;k<K;k++){ //shiftdown k times to find k biggest
temp1=heap[--n]; //numbers with Θ(klogN)
heap[n] = heap[0];
heap[0] = temp1;
if(n!=0) {
i=0;
while(!((i>=n/2)&&(i<n))){
j = 2*i+1;
rc = 2*i+2;
if((rc<n)&&(heap[j]<heap[rc])) j=rc;
if(heap[i]>heap[j]) break;
temp = heap[i];
heap[i]=heap[j];
heap[j]=temp;
i=j;
}
}
}
cout<<heap[length-K]<<endl;
for(i=0;i<length-K;i++)
cout<<heap[i]<<" ";
return 0;
}
It’s all right but one of datas is Time Limit Exceed ,I am so confused with how to solve this problem.
Your sift-down operation doesn’t seem correct. There shouldn’t be two nested loops there. You should just start at the root and keep swapping it with one of its children until it’s larger than both. The outer loop
for(i=n/2-1;i>=0;i--)shouldn’t be there (it causes each sift-down to takeO(n)) – I think you should just setito 0 to start at the root.Edit: Your heapify operation is too slow as well: You are using the same loop variable
ifor both the outer and inner loop, so it will alternately grow larger and smaller. The inner loop should start with the outer loop’si, but shouldn’t affect the value ofiin the outer loop’s next iteration. I suggest putting the sift-down operation in its own function. This will both fix this problem, and avoid having sift-down coded twice.