TopK问题介绍:
在N个数中找出最大/小的前K个 (比如在1000个数中找出最大/小的前10个)
以前的方法:冒泡排序。时间复杂度: O(N^2)
现在找最大的k个数的方法:
方法1:堆排序降序,前N个就是最大的。上篇学过时间复杂度: O(N*logN)
方法2:N个数依次插入大堆,HeapPop K次,每次取堆顶的数据,即为前K个。
时间复杂度: O(K*logN)
假设 N非常大, 是 10 亿,内存中存不下这些数,它们存在文件中的。 K是 100,
上面的方法就都不能用了……
话说 10 亿个整数,大概占用多少空间?
1G = 1024MB
1G = 1024*1024KB
1G = 1024*1024*1024Byte
要占用10亿字节!所以我们来看看方法3:
方法3:
   这里为什么使用小堆而不使用大堆?
最大的前K个数一定会比其他数要大,只要进来的数比堆顶数据大,就替代它。
因为是小堆(小的在上大的在下),最大的数进去后一定会沉到下面,
所以不可能存在大的数堵在堆顶导致某个数进不去的情况,数越大沉得越深。
对应地,如果使用大堆就会出现一个大数堵在堆顶,剩下的数都比这个大数小,
导致其他数进不来,最后只能选出最大的那一个。
剑指 Offer 40. 最小的k个数
难度简单
输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,
则最小的4个数字是1、2、3、4。
示例 1:
输入:arr = [3,2,1], k = 2
输出:[1,2] 或者 [2,1]
示例 2:
输入:arr = [0,1,2,1], k = 1
输出:[0]
限制:
0 <= k <= arr.length <= 10000
0 <= arr[i] <= 10000
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* getLeastNumbers(int* arr, int arrSize, int k, int* returnSize){
}
 解析代码:
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
void justDown(int* arr, int n, int root)//大堆下调
{
    int father = root;
    int child = father * 2 + 1;//默认左孩子大
    while (child < n)
    {
        if (child + 1 < n && arr[child] < arr[child + 1])
        {  // 如果右孩子存在且右孩子比左孩子大
            child++;
        }
        if (arr[father] < arr[child])
        {
            int tmp = arr[father];
            arr[father] = arr[child];
            arr[child] = tmp;
            father = child;
            child = father * 2 + 1;
        }
        else
        {
            break;
        }
    }
}
int* getLeastNumbers(int* arr, int arrSize, int k, int* returnSize) {
    *returnSize = k;
    if (k == 0)//回头处理k==0
    {
        return NULL;
    }
    int* retArr = (int*)malloc(sizeof(int) * k);
    for (int i = 0;i < k;i++)
    {
        retArr[i] = arr[i];
    }
    for (int i = (k - 1 - 1) / 2;i >= 0;i--) //建堆的for写法
    {
        justDown(retArr, k, i);
    }
    for (int j = k;j < arrSize;j++)
    {
        if (arr[j] < retArr[0])
        {
            retArr[0] = arr[j];
            justDown(retArr, k, 0);
        }
    }
    //*returnSize = k; 写到这发现有个测试用例跑不了,到上面处理一下
    return retArr;
}
 



















