题目描述:
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。
分析:建一个K大小的大根堆,存储最小的k个数字。
先将K个数进堆,然后调整堆为大根堆。
之后每加一个数,就和堆的根结点比较。
如果大于堆的根结点,则忽略。否则,替换根结点的值,然后调整堆。
最后,剩下的就是其中最小的K个数。
代码:1 class Solution { 2 public: 3 vector GetLeastNumbers_Solution(vector input, int k) { 4 int iSize = input.size(); 5 if(k == iSize) return input; 6 vector leastNumbers; 7 if(k <= 0 || k > iSize) return leastNumbers; 8 leastNumbers.push_back(0); // 使下标为0的位置为0,不使用该位置,便于访问后面的元素 9 for(int i = 0; i < k; i++) { // 初始化一个k大小的堆10 leastNumbers.push_back(input[i]);11 }12 for(int i = k / 2; i > 0; --i) {13 HeapAdjust(leastNumbers, i, k); // 调整为大根堆14 }15 for(int i = k; i < iSize; i++) {16 if(input[i] < leastNumbers[1]) {17 leastNumbers[1] = input[i];18 HeapAdjust(leastNumbers, 1, k); // 调整为大根堆19 }20 }21 leastNumbers.erase(leastNumbers.begin()); // 移除第0位置的022 return leastNumbers;23 }24 25 void HeapAdjust(vector &input, int s, int m) { // 调整堆26 int rc = input[s];27 for(int j = (s << 1); j <= m; j <<= 1) {28 if(j < m && input[j] < input[j + 1]) ++j;29 if(rc > input[j]) break;30 input[s] = input[j];31 s = j;32 }33 input[s] = rc;34 }35 };