100w个数中找出最大的前K个数
100w个数中找出最大的前K个数这个题是堆应用。
首先100万个数大约占4M内存,可以加载到内存中。我们可以采用排序解决这个问题,比如堆排序、快排等,但排序不是最优解。我们可以利用最小堆来解决这个问题。
堆数据结构是一种数组对象,它可以被视为一棵完全二叉树结构。 堆结构的二叉树存储是 最大堆:每个父节点的都大于孩子节点。 最小堆:每个父节点的都小于孩子节点。 思路:1、开辟大小为k的空间,把数组中前k个数建小堆 2、把剩下的数依次和堆顶元素进行比较,如果后面的数大于堆顶,替换掉堆顶,重新调整为最小堆,直到把剩下的数与堆顶比较完,此时堆里的k个数就是最大的前k个数#include<iostream> using namespace std; void _Adjustdown(int* arr, int size, int parent) { int child = parent * 2 + 1; while (child < size) { //比较左右节点,选择较小的 if (child + 1 < size && arr[child] > arr[child + 1]) { child++; } if (arr[parent] > arr[child]) { swap(arr[parent],arr[child]); parent = child; child = parent * 2 + 1; } else { break; } } } //建小堆 void BuildHeap(int *arr,int size) { //从第一个非叶子节点开始向下调整 for (int i = (size-2)/ 2; i >= 0; --i) { _Adjustdown(arr, size, i); } } void GetKTop(int* arr,int size,int k) { if (size<k || k<=0) { return; } //开辟大小为k的空间,把数组中前k个数建小堆 int *heap = new int[k]; for (int i = 0; i < k; ++i) { heap[i] = arr[i]; } BuildHeap(heap,k); //把后面的数依次和堆顶比较 for (int i = k; i<size; ++i) { //如果后面的数大于堆顶,替换掉堆顶,重新调整为最小堆 if (arr[i]>heap[0]) { heap[0] = arr[i]; _Adjustdown(heap, k, 0); } } for (int i = 0; i < k; ++i) { cout << heap[i] << " "; } delete[] heap; } int main() { int arr[] = {1,2,5,6,7,9,2,5,10,22,40,35}; int size = sizeof(arr) / sizeof(arr[0]); GetKTop(arr,size,3); return 0; }
如果用堆排序解决问题,需要把所有数进行建堆,建堆的时间复杂度O(lgN),如果只把前k个数建堆,时间复杂度O(lgk),k远小于N,效率比堆排序高。
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
- 上一篇:没有了
- 下一篇:没有了