- 题目描述:
-
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
- 输入:
-
每个测试案例包括2行:
第一行为2个整数n,k(1<=n,k<=200000),表示数组的长度。
第二行包含n个整数,表示这n个数,数组中的数的范围是[0,1000 000 000]。
- 输出:
-
对应每个测试案例,输出最小的k个数,并按从小到大顺序打印。
- 样例输入:
-
8 4 4 5 1 6 2 7 3 8
- 样例输出:
-
1 2 3 4
可以用一个K大小的最大队来做,当堆的个数<K时放入,否则当堆的根大于当前数,弹出堆的根,插入当前数。另外一种就是用partition来找第K大数,这样它前面的保证都是比它小的,所以K个数就找到了。1 #include <iostream> 2 #include <vector> 3 #include <cstdio> 4 #include <queue> 5 using namespace std; 6 7 void print(priority_queue<int, vector<int>, less<int> > &maxHeap) 8 { 9 if (maxHeap.empty()) 10 return; 11 12 int element = maxHeap.top(); 13 maxHeap.pop(); 14 bool status = maxHeap.empty(); 15 16 print(maxHeap); 17 18 if (status) 19 printf("%d", element); 20 else 21 printf(" %d", element); 22 } 23 24 int main() 25 { 26 int n, k; 27 28 while(scanf("%d%d", &n, &k) != EOF) 29 { 30 priority_queue<int, vector<int>, less<int> > maxHeap; 31 32 int num; 33 for(int i = 0; i < n; i++) 34 { 35 scanf("%d", &num); 36 if (maxHeap.size() < k) 37 maxHeap.push(num); 38 else 39 { 40 if (maxHeap.top() > num) 41 { 42 maxHeap.pop(); 43 maxHeap.push(num); 44 } 45 } 46 } 47 48 print(maxHeap); 49 printf("\n"); 50 } 51 }
#include <iostream> #include <ctime> #include <algorithm> #include <cstdio> using namespace std; void partition(int a[], int left, int right, int k) { int randNum = left + (rand() % (right - left + 1)); int t = a[randNum]; a[randNum] = a[left]; a[left] = t; int i = left; int j = right; int key = a[left]; while(i <= j) { if (a[i] <= key) i++; else { int t = a[j]; a[j] = a[i]; a[i] = t; j--; } } a[left] = a[j]; a[j] = key; if (j == k) return; else if (j > k) return partition(a, left, j - 1, k); else return partition(a, j + 1, right, k); } int main() { int n, k; int a[200000]; while(scanf("%d%d", &n, &k) != EOF) { for(int i = 0; i < n; i++) scanf("%d", &a[i]); srand(time(NULL)); partition(a, 0, n - 1, k - 1); sort(a, a + k); for(int i = 0; i < k; i++) if (i == 0) printf("%d", a[i]); else printf(" %d", a[i]); printf("\n"); } }