10G整数,找出中位数
摘自:
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整数,找出中位数的更多相关文章
- 在一个文件中有10G个整数,乱序排列,要求找出中位数
题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数.内存限制为 2G.只写出思路即可(内存限制为 2G的意思就是,可以使用2G的空间来运行程序,而不考虑这台机器上的其他软件的占用内存). ...
- 【转】文件中有10G个整数,乱序排列,要求找出中位数
题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数.内存限制为 2G.只写出思路即可(内存限制为 2G的意思就是,可以使用2G的空间来运行程序,而不考虑这台机器上的其他软件的占用内存). ...
- 腾讯面试题:10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。
腾讯面试题:10G 个整数,乱序排列,要求找出中位数.内存限制为 2G. 题目和基本思路都来源网上,本人加以整理. 题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数.内存限制为 2G.只 ...
- 10G个64bit整数,找出中位数
[10G个64bit整数,找出中位数] 题目:在一个文件中有10G个64bit整数,乱序排列,要求找出中位数.内存限制为2G. 解法:内存限制为2G表面上是限制,实际上是一种提示,在提示我们如何利用2 ...
- 面试题:在一个文件中有 10G 个整数,乱序排列,要求找出中位数(内存限制为2G)
假设整数为32bit,4个字节存储 这种题目,首先想到的是分而治之.将文件中数字分组.然后遍历文件中的数字,按分组进行计数.最后找到中位数所在的分组区间 1.如果10G个整数都为同一个,那么10G整数 ...
- 一个很大的文件,存放了10G个整数的乱序数列,如何用程序找出中位数。
一.梳理审题 一.看清题目: 注意这个题目的量词,这个文件中有10G个整数,而不是这个文件占了10G的内存空间. 二.一些疑问: 在计算机中我们讲的G.M等都是存储容量的概念,但是一般都会在会面加上B ...
- 10G整数文件中寻找中位数或者第K大数
来源:http://hxraid.iteye.com/blog/649831 题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数.内存限制为 2G.只写出思路即可(内存限制为 2G的意思就 ...
- [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 ...
- LeetCode练习4 找出这两个有序数组的中位数
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 nums1 和 nums2 ...
随机推荐
- top 学习
通常top命令是会持续运行而不终止的. 要在脚本里用,需要添加一些选项参数,尤其是-b.例如:top -b -n 2 -d 3 >/tmp/log -b表示批处理模式(Batch mode),以 ...
- Linux系统排查——CPU负载篇
本随笔介绍CPU负载的排查手段. 查看系统负载的工具:uptime,w,都能查看系统负载,系统平均负载是处于运行或不可打扰状态的进程的平均数, 可运行:运行态,占用CPU,或就绪态,等待CPU调度. ...
- debian8最小化安装,字符界面的中文配置
一.现象: debian8最小化安装以后,字符界面的中文显示乱码. 二.解决 1. 安装locales apt-get install locales 2. 配置locales dpkg-reconf ...
- Linux下Socket网络编程
什么是Socket Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序.要学Internet上的TCP/IP网络编程, ...
- [转]Java中Runtime.exec的一些事
0 预备知识 1 不正确的调用exitValue 2不正确的调用waitFor 3 一种可接受的调用方式 4 调用认为是可执行程序的时候容易发生的错误 5 window执行的良好示例 6 不良好的重定 ...
- 用python参加Kaggle的经验总结【转】
用python参加Kaggle的经验总结 转载自:http://www.jianshu.com/p/32def2294ae6,作者 JxKing 最近挤出时间,用python在kaggle上试了 ...
- django -- 对模式进行调式(pay with the api)
在django中如果想对models进行调试.不用每次都要runserver 在web界面上点点点.django自己带了字符界面的调试功能 一.完成app的注册.与models的定义: 注册app: ...
- 安装python 2.7条件下的pip环境
wget https://pypi.python.org/packages/ff/d4/209f4939c49e31f5524fa0027bf1c8ec3107abaf7c61fdaad704a648 ...
- [LeetCode] Contains Duplicate & Contains Duplicate II
Contains Duplicate Given an array of integers, find if the array contains any duplicates. Your funct ...
- apache-tomcat-7.0.53-windows-x86或者x64:出现错误提示:(Unable to open the service 'tomcat7)或者(Failed installing 'Tomcat7' service) tomcat7 %1 不是有效的 Win32 应用程序。
具体 安装行动 :打开下令 行提醒 符窗口 => 进入Tomcat安装目次 ==> 进入bin目次 下==> 输入:service.bat install 即可而且tomcat_ho ...