题目描述:
面试题 17.14. 最小K个数
设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。
示例:
输入: arr = [1,3,5,7,2,4,6,8], k = 4
输出: [1,2,3,4]
提示:
0 <= len(arr) <= 100000
0 <= k <= min(100000, len(arr))
这题很明显可以使用一个小根堆来解决:
1.首先在给定数组构造一个小根堆;
2.然后每次取出最小的元素加入答案的数组,然后整堆即可即可。
时间分析:
1.建堆的时间是接近线性的,最坏也不会超过nlogn;
2.每次取出元素和整堆是O(logn)的,所以总的时间是O(nlogn)的。
内存分析:
1.除了答案数组似乎不消耗啥。
代码
void swap(int *x, int *y){
int tmp = *x;
*x = *y;
*y = tmp;
}
void push_down(int heap[], int i, int heap_size){//下推
int max_index = -1;
int l = i*2+1, r = (i+1)*2;
if(l < heap_size && heap[l] < heap[i]) max_index = l;
else max_index = i;
if(r < heap_size && heap[r] < heap[max_index]) max_index = r;
if(i != max_index){
swap(&heap[i], &heap[max_index]);
push_down(heap, max_index, heap_size);
}
}
void build_heap(int heap[], int heap_size){//建堆
for(int i = heap_size/2-1; i >= 0; i--){
push_down(heap, i, heap_size);
}
}
int get_min(int heap[], int heap_size){//取出最小元素
int min = heap[0];
swap(&heap[0], &heap[heap_size-1]);
push_down(heap, 0, heap_size-1);
return min;
}
如有错误欢迎指出。