输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。
思路:针对海量数据
(1)先把数组中前K个数据建成大堆
(2)然后剩下的N-K个数跟堆顶数据比较,若比堆顶数据小,则替换堆顶的数据,调整堆
(3)最后堆里面就是最小的K个数
时间复杂度:O(N*logK)
空间复杂度:O(K)
//时间复杂度:O(N*logK) 空间复杂度:O(K)
int* getLeastNumbers(int* arr, int arrSize, int k, int* returnSize){
if(k ==0)
{
*returnSize = 0;
return NULL;
}
int* arrRet = (int*)malloc(sizeof(int)*k);
//前k个数建立大堆
for(int i = 0; i <k; i++) //将arr数组中前K个数将其给到arrRet数组中
{
arrRet[i] = arr[i];
}
for(int j = (k-1-1); j >=0; j--) //把前K个数向下调整成为大堆
{
AdjustDown(arrRet,k,j);
}
//剩下的N-K个数,比堆顶的小,就替换堆顶数据,进堆
for(int i = k; i < arrSize; i++)
{
if(arr[i] < arrRet[0])
{
arrRet[0] = arr[i];
AdjustDown(arrRet,k,0);
}
}
*returnSize = k;
return arrRet;
}
//1. 找最大的K个元素
//假设堆为小堆
void PrintTopK(int* a, int n, int k)
{
Heap hp;
//建立含有K个元素的堆
HeapInit(&hp, a, k);
for (size_t i = k; i < n; ++i) // N
{
//每次和堆顶元素比较,大于堆顶元素,则删除堆顶元素,插入新的元素
if (a[i] > HeapTop(&hp)) // LogK
{
HeapPop(&hp);
HeapPush(&hp, a[i]);
}
}
for(int i = 0; i < k; ++i){
printf("%d ",HeapTop(&hp));
HeapPop(&hp);
}
}
//2. 找最小的K个元素
//假设堆为大堆
void PrintTopK(int* a, int n, int k)
{
Heap hp;
//建立含有K个元素的堆
HeapInit(&hp, a, k);
for (size_t i = k; i < n; ++i) // N
{
//每次和堆顶元素比较,小于堆顶元素,则删除堆顶元素,插入新的元素
if (a[i] < HeapTop(&hp)) // LogK
{
HeapPop(&hp);
HeapPush(&hp, a[i]);
}
}
for(int i = 0; i < k; ++i){
printf("%d ",HeapTop(&hp));
HeapPop(&hp);
}
}