获取第K大的数
- 使用快速排序,从数组中随机找出一个元素X,把数组分成比X小和比X大的两部分,假设比X小的部分元素个数为B,则:
(1) 如果B >= K,则递归从比X小的部分找第K大的元素。
(2) 如果B < K,则递归从比X大的部分找第(K-B)大的元素。
2.
(1) 使用最小堆,类似笔试题中O(NlogM)的算法。
(2) 使用最大堆,类似于笔试题中O(MlogN)的算法。
int getparent(int begin,int end,int index){ int parentindex = (index-begin-1)/2+begin; return parentindex; } int getlchild(int begin,int end,int index){ int lchildindex = (index - begin) * 2 + 1 + begin; return lchildindex; } int getrchild(int begin,int end,int index){ int rchildindex = (index - begin) * 2 + 1 + begin + 1; return rchildindex; } void adjustheap(vector<int> & v,int begin,int end,int index){ int lchild = getlchild(begin,end,index); int rchild = getrchild(begin,end,index); int largest = index; if( rchild <= end && v[rchild] > v[largest] ) largest = rchild; if( lchild <= end && v[lchild] > v[largest] ) largest = lchild; if(largest != index){ int temp = v[largest]; v[largest] = v[index]; v[index] = temp; adjustheap(v,begin,end,largest); } // show(v,begin,end); } void buildmaxheap(vector<int> & v,int begin,int end){ int parent = getparent(begin,end,end); while(parent >= begin){ adjustheap(v,begin,end,parent); parent--; } } void heapsort(vector<int> & v,int begin,int end){ buildmaxheap(v,begin,end); // show(v,begin,end); int tempend = end; for( ; tempend > begin; ){ int temp = v[begin]; v[begin] = v[tempend]; v[tempend] = temp; adjustheap(v,begin,--tempend,begin); } } int getKmaxbyheapsort(vector<int> & v,int begin,int end,int K){ //这个跟完全堆排序步骤是差不多的,不过步骤循环次数有减少了 buildmaxheap(v,begin,end); int i = 0 ; int temp = 0; for( ; i < K ; i++){ temp = v[begin]; v[begin] = v[end]; v[end] = temp; adjustheap(v,begin,--end,begin); } return temp; }
//类似快速排序的方式
int partition(vector<int> & v,int begin,int end){ int key = v[begin]; int i = begin; int j = end; while(i<j){ while(j>i && v[j] <= key) j--; while(j>i && v[i] > key) i++; int temp = v[j]; v[j] = v[i]; v[i] = temp; } v[i] = key; return i; } void quicksort(vector<int> & v,int begin,int end){ if(begin < end){ int mid = partition(v,begin,end); quicksort(v,begin,mid-1); quicksort(v,mid+1,end); } } int getKmaxbyQuicksort(vector<int> & v,int begin,int end,int K){ if(begin == end) return v[begin]; int mid = partition(v,begin,end); int num = mid - begin + 1; if(num == K ){ return v[begin + K]; } if( num > K){ return getKmaxbyQuicksort(v,begin,mid-1,K); } if( num < K){ return getKmaxbyQuicksort(v,mid+1,end,K-num); } }