[CareerCup] 18.6 Smallest One Million Numbers 最小的一百万个数字

简介:

18.6 Describe an algorithm to find the smallest one million numbers in one billion numbers. Assume that the computer memory can hold all one billion numbers.

这道题让我们在十亿个数字中找到最小的一百万个数字,而且限定了计算机只有能存十亿个数字的内存。这题有三种解法,排序,最小堆,和选择排序。

首先来看排序方法,这种方法简单明了,就是把这十亿个数字按升序排列,然后返回前一百万个即可,时间复杂度是O(nlgn)。

然后来看最小堆做法,我们建立一个最大堆(大的数字在顶端),然后将前一百万个数字加进去。然后我们开始遍历剩下的数字,对于每一个数字,我们将其加入堆中,然后删掉堆中最大的数字。遍历接受后,我们就有了一百万个最小的数字,时间复杂度是O(nlgm),其中m是我们需要找的数字个数。

最后我们来看选择排序的方法,这种方法可以在线性时间内找到第i个最大或最小的数,如果数字都不是不同的,那么我们可以在O(n)的时间内找到第i个最小的数字,算法如下:

1. 随机选取数组中的一个数字当做pivot,然后以此来分割数组,记录分割处左边的数字的个数。

2. 如果左边正好有i个数字,那么返回左边最大的数字。

3. 如果左边数字个数大于i,那么继续在左边递归调用这个方法。

4. 如果左边数字个数小于i,那么在右边递归调用这个方法,但是此时的rank变为i - left_size。

参见代码如下:

int partition(vector<int> &array, int left, int right, int pivot) {
    while (true) {
        while (left <= right && array[left] <= pivot) ++left;
        while (left <= right && array[right] > pivot) --right;
        if (left >right) return left - 1;
        swap(array[left], array[right]);
    }
}

int find_max(vector<int> &array, int left, int right) {
    int res = INT_MIN;
    for (int i = left; i <= right; ++i) {
        res = max(res, array[i]);
    }
    return res;
}

int selection_rank(vector<int> &array, int left, int right, int rank) {
    int pivot = array[rand() % (right - left + 1) + left];
    int left_end = partition(array, left, right, pivot);
    int left_size = left_end - left + 1;
    if (left_size == rank + 1) return find_max(array, left, left_end);
    else if (rank < left_size) return selection_rank(array, left, left_end, rank);
    else return selection_rank(array, left_end + 1, right, rank - left_size);
}

本文转自博客园Grandyang的博客,原文链接:最小的一百万个数字[CareerCup] 18.6 Smallest One Million Numbers ,如需转载请自行联系原博主。

相关文章
|
C++
【C++】缺省参数(默认参数)
【C++】缺省参数(默认参数)
176 3
|
SpringCloudAlibaba Java 网络架构
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(七)Spring Cloud Gateway服务网关
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(七)Spring Cloud Gateway服务网关
1119 0
|
C语言
C 语言三大结构之循环结构
C 语言三大结构之循环结构
123 0
|
人工智能 物联网 数据库
微软 Build 2017 开发者大会:Azure 与 AI 的快速发展
一年一度的微软 Build 大会准时起航,本年度大会从旧金山移师西雅图,一个近年来凭借女神汤唯而在中国家喻户晓的美国西部海滨城市。 距离开场15分钟,大会主会场已经就绪。 会议开头是一个 MineCraft 拼出的 Seattle。
1360 0
|
19小时前
|
云安全 人工智能 自然语言处理
|
5天前
|
搜索推荐 编译器 Linux
一个可用于企业开发及通用跨平台的Makefile文件
一款适用于企业级开发的通用跨平台Makefile,支持C/C++混合编译、多目标输出(可执行文件、静态/动态库)、Release/Debug版本管理。配置简洁,仅需修改带`MF_CONFIGURE_`前缀的变量,支持脚本化配置与子Makefile管理,具备完善日志、错误提示和跨平台兼容性,附详细文档与示例,便于学习与集成。
310 116
|
8天前
|
数据采集 人工智能 自然语言处理
Meta SAM3开源:让图像分割,听懂你的话
Meta发布并开源SAM 3,首个支持文本或视觉提示的统一图像视频分割模型,可精准分割“红色条纹伞”等开放词汇概念,覆盖400万独特概念,性能达人类水平75%–80%,推动视觉分割新突破。
550 51
Meta SAM3开源:让图像分割,听懂你的话