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 - ;
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 + ) + left];
int left_end = partition(array, left, right, pivot);
int left_size = left_end - left + ;
if (left_size == rank + ) 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 + , right, rank - left_size);
}

一旦找到了第i个最小的数字后,就可以遍历整个数组来找所有小于等于该数字的元素。当数组有重复元素的话,需要修改一些地方,但是时间就不能保证是线性的了。其实也有算法能线性时间内处理有重复的数组,但是比较复杂,有兴趣的请自行搜索研究。

CareerCup All in One 题目汇总

[CareerCup] 18.6 Smallest One Million Numbers 最小的一百万个数字的更多相关文章

  1. [CareerCup] 18.1 Add Two Numbers 两数相加

    18.1 Write a function that adds two numbers. You should not use + or any arithmetic operators. 这道题让我 ...

  2. [CareerCup] 18.9 Find and Maintain the Median Value 寻找和维护中位数

    18.9 Numbers are randomly generated and passed to a method. Write a program to find and maintain the ...

  3. [LeetCode] Find K Pairs with Smallest Sums 找和最小的K对数字

    You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k. Define ...

  4. [CareerCup] 18.12 Largest Sum Submatrix 和最大的子矩阵

    18.12 Given an NxN matrix of positive and negative integers, write code to find the submatrix with t ...

  5. [CareerCup] 18.11 Maximum Subsquare 最大子方形

    18.11 Imagine you have a square matrix, where each cell (pixel) is either black or white. Design an ...

  6. [CareerCup] 18.10 Word Transform 单词转换

    18.10 Given two words of equal length that are in a dictionary, write a method to transform one word ...

  7. [CareerCup] 18.8 Search String 搜索字符串

    18.8 Given a string s and an array of smaller strings T, design a method to search s for each small ...

  8. [CareerCup] 18.5 Shortest Distance between Two Words 两单词间的最短距离

    18.5 You have a large text file containing words. Given any two words, find the shortest distance (i ...

  9. [CareerCup] 18.4 Count Number of Two 统计数字2的个数

    18.4 Write a method to count the number of 2s between 0 and n. 这道题给了我们一个整数n,让我们求[0,n]区间内所有2出现的个数,比如如 ...

随机推荐

  1. memcpy与memmove的区别

    在面试中经常会被问道memcpy与memove有什么区别? 整理如下: 其实主要在考C的关键字:restrict C库中有两个函数可以从一个位置把字节复制到另一个位置.在C99标准下,它们的原型如下: ...

  2. Cygwin的安装与配置

    去cygwin的官网去下载: 安装: 初次安装 卸载 使用过程中安装新的工具包 参考http://blog.csdn.net/superbinbin1/article/details/10147421 ...

  3. HDU 5807 Keep In Touch DP

    Keep In Touch Problem Description   There are n cities numbered with successive integers from 1 to n ...

  4. ubuntu 安装fcitx输入法

    ubuntu 14 的环境 我用的ibus输入法和firefox 36.0.4 版本相互冲突,有bug.在输入栏无法选中,以及复制.查其原因是ibus输入法有问题,需要重新换个输入法. 我先卸载了ib ...

  5. JDBC操作MySQL数据库案例

    JDBC操作MySQL数据库案例 import java.sql.Connection; import java.sql.DriverManager; import java.sql.Prepared ...

  6. 【spring bean】spring中bean的懒加载和depends-on属性设置

    项目结构如下: ResourceBean.java代码: package com.it.res; import java.io.File; import java.io.FileNotFoundExc ...

  7. asp.net项目中通过Web.config配置文件及文件夹的访问权限!

    描述:在开发中我们通常会碰到这样的问题,例如:在项目的根目录下面有一个文件或者文件夹需要用户登陆后才能访问.如果用户在没有登录的情况下访问该文件或者该文件夹下面的文件时,直接拦截重定向到对应的登陆页面 ...

  8. 廖雪峰js教程笔记3

    JavaScript的函数在查找变量时从自身函数定义开始,从"内"向"外"查找.如果内部函数定义了与外部函数重名的变量,则内部函数的变量将"屏蔽&qu ...

  9. Hi,我还没死(屎)

    HDNOIP没考好,紧接着NOIP又到了,加紧练习:-)

  10. struts2总结三:struts2配置文件struts.xml的简单总结

    一.struts中的常量constant的配置. 在struts2中同一个常量的配置有三种方式,第一种在struts.xml中,第二种在struts.properties中配置,第三种在web.xml ...