摘自:

http://www.cnblogs.com/avril/archive/2012/04/20/2460805.html

http://blog.csdn.net/flyinghearts/article/details/5623975

题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。只写出思路即可(内存限制为 2G的意思就是,可以使用2G的空间来运行程序,而不考虑这台机器上的其他软件的占用内存)。

关于中位数:数据排序后,位置在最中间的数值。即将数据分 成两部分,一部分大于该数值,一部分小于该数值。中位数的位置:当样本数为奇数时,中位数=(N+1)/2 ; 当样本数为偶数时,中位数为N/2与1+N/2的均值(那么10G个数的中位数,就第5G大的数与第5G+1大的数的均值了)。

分析:明显是一道工程性很强的题目,和一般的查找中位数的题目有几点不同。
1. 原数据不能读进内存,不然可以用快速选择,如果数的范围合适的话还可以考虑桶排序或者计数排序,但这里假设是32位整数,仍有4G种取值,需要一个16G大小的数组来计数。

2. 若看成从N个数中找出第K大的数,如果K个数可以读进内存,可以利用最小或最大堆,但这里K=N/2,有5G个数,仍然不能读进内存。

3. 接上,对于N个数和K个数都不能一次读进内存的情况,《编程之美》里给出一个方案:设k<K,且k个数可以完全读进内存,那么先构建k个数的堆,先 找出第0到k大的数,再扫描一遍数组找出第k+1到2k的数,再扫描直到找出第K个数。虽然每次时间大约是nlog(k),但需要扫描ceil(K/k) 次,这里要扫描5次。

解法:首先假设是32位无符号整数。
1. 读一遍10G个整数,把整数映射到256M个区段中,用一个64位无符号整数给每个相应区段记数。
说 明:整数范围是0 - 2^32 - 1,一共有4G种取值,映射到256M个区段,则每个区段有16(4G/256M = 16)种值,每16个值算一段, 0~15是第1段,16~31是第2段,……2^32-16 ~2^32-1是第256M段。一个64位无符号整数最大值是0~8G-1,这里先不考虑溢出的情况。总共占用内存256M×8B=2GB。

2. 从前到后对每一段的计数累加,当累加的和超过5G时停止,找出这个区段(即累加停止时达到的区段,也是中位数所在的区段)的数值范围,设为[a,a+15],同时记录累加到前一个区段的总数,设为m。然后,释放除这个区段占用的内存。

3. 再读一遍10G个整数,把在[a,a+15]内的每个值计数,即有16个计数。

4. 对新的计数依次累加,每次的和设为n,当m+n的值超过5G时停止,此时的这个计数所对应的数就是中位数。

总结:
1.以上方法只要读两遍整数,对每个整数也只是常数时间的操作,总体来说是线性时间。

2. 考虑其他情况。
若是有符号的整数,只需改变 映射即可。若是64为整数,则增加每个区段的范围,那么在第二次读数时,要考虑更多的计数。若过某个计数溢出,那么可认定所在的区段或代表整数为所求,这 里只需做好相应的处理。噢,忘了还要找第5G+1大的数了,相信有了以上的成果,找到这个数也不难了吧。

3. 时空权衡。
花费256个区段也许只是恰好配合2GB的内存(其实也不是,呵呵)。可以增大区段范围,减少区段数目,节省一些内存,虽然增加第二部分的对单个数值的计数,但第一部分对每个区段的计数加快了(总体改变??待测)。

4. 映射时尽量用位操作,由于每个区段的起点都是2的整数幂,映射起来也很方便。

10G整数,找出中位数的更多相关文章

  1. 在一个文件中有10G个整数,乱序排列,要求找出中位数

     题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数.内存限制为 2G.只写出思路即可(内存限制为 2G的意思就是,可以使用2G的空间来运行程序,而不考虑这台机器上的其他软件的占用内存). ...

  2. 【转】文件中有10G个整数,乱序排列,要求找出中位数

    题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数.内存限制为 2G.只写出思路即可(内存限制为 2G的意思就是,可以使用2G的空间来运行程序,而不考虑这台机器上的其他软件的占用内存). ...

  3. 腾讯面试题:10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。

    腾讯面试题:10G 个整数,乱序排列,要求找出中位数.内存限制为 2G. 题目和基本思路都来源网上,本人加以整理. 题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数.内存限制为 2G.只 ...

  4. 10G个64bit整数,找出中位数

    [10G个64bit整数,找出中位数] 题目:在一个文件中有10G个64bit整数,乱序排列,要求找出中位数.内存限制为2G. 解法:内存限制为2G表面上是限制,实际上是一种提示,在提示我们如何利用2 ...

  5. 面试题:在一个文件中有 10G 个整数,乱序排列,要求找出中位数(内存限制为2G)

    假设整数为32bit,4个字节存储 这种题目,首先想到的是分而治之.将文件中数字分组.然后遍历文件中的数字,按分组进行计数.最后找到中位数所在的分组区间 1.如果10G个整数都为同一个,那么10G整数 ...

  6. 一个很大的文件,存放了10G个整数的乱序数列,如何用程序找出中位数。

    一.梳理审题 一.看清题目: 注意这个题目的量词,这个文件中有10G个整数,而不是这个文件占了10G的内存空间. 二.一些疑问: 在计算机中我们讲的G.M等都是存储容量的概念,但是一般都会在会面加上B ...

  7. 10G整数文件中寻找中位数或者第K大数

    来源:http://hxraid.iteye.com/blog/649831 题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数.内存限制为 2G.只写出思路即可(内存限制为 2G的意思就 ...

  8. [LeetCode] Find Median from Data Stream 找出数据流的中位数

    Median is the middle value in an ordered integer list. If the size of the list is even, there is no ...

  9. LeetCode练习4 找出这两个有序数组的中位数

    给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 nums1 和 nums2  ...

随机推荐

  1. ASP.NET MVC3 Model验证总结 @Html.ValidationSummary(true)

    http://www.wyjexplorer.cn/Post/2012/8/3/model-validation-in-aspnet-mvc3 ASP.NET MVC3中的Model是自验证的,这是通 ...

  2. Git 分支(分布式版本控制系统)

    前言 几乎所有的版本控制系统都以某种形式支持分支.使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响开发主线.在很多版本控制系统中,这是一个略微低效的过程--常常需要完全创建一个源代码目录的 ...

  3. HANA初印象

    今天手懒,看了一些SAP HANA 的一些外文介绍,不翻译了,直接剽窃过来,供参考. 1. HANA 是什么东西? “HANA doesn't actually mean anything, but ...

  4. linux中chkconfig 启动程序顺序介绍

    1)redhat的启动方式和执行次序是: 加载内核 执行init程序 /etc/rc.d/rc.sysinit          # 由init执行的第一个脚本 /etc/rc.d/rc $RUNLE ...

  5. sqlserver使用存储过程发送http请求

    本文主要向大家介绍了SQLServer数据库访问发送Http请求,通过具体的内容向大家展现,希望对大家学习SQLServer数据库有所帮助. -- 通用读取获取数据存储过程 --开启Sql Serve ...

  6. HTC T329手机如何删除系统自带的软件?HTC一键解锁、获取ROOT权限、豌豆荚删除系统软件

    手头一部HTC T329T手机,机上默认装载的软件实在太多了,居然占用了4页.用360手机卫士并不能删除系统软件(不能获取ROOT权限).查网上查询,总结要删除系统软件步骤如下(本人不刷机,只是想删除 ...

  7. 快学Scala习题解答—第四章 映射和元组

    4 映射和元组  4.1 设置一个映射,当中包括你想要的一些装备,以及它们的价格.然后构建还有一个映射.採用同一组键,可是价格上打9折 映射的简单操作  ,"gun"->18 ...

  8. cocos2d-x 模态对话框的实现

    心情不好,恩.不扯淡了.直接讲. ================================== 在泰然看了一篇实现模态对话框的文章,写的还不错,然后在其基础上加了我简单加了一层灰色透明背景,这 ...

  9. 【Java】日志知识总结和经常使用组合配置(commons-logging,log4j,slf4j,logback)

    Log4j Apache的一个开放源码项目,通过使用Log4j,我们能够控制日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接口服务 器.NT的事件记录器.UNIX Syslog守护进程等.用 ...

  10. 【iOS XMPP】使用XMPPFramewok(二):用户登录

    转自:http://www.cnblogs.com/dyingbleed/archive/2013/05/10/3069397.html 用户登录 准备工作 比较知名的开源XMPP服务器:一个是Ope ...