从1亿个数字中取出最大的100个数字- 位图排序(空间换时间)
2017-04-27 17:26
330 查看
/* *一个排序算法题:从1亿个数字中取出最大的100个 *装逼宝典:位图公式 bitmap[arr[i]]=1; 将传统数组转换为位图数组就完成了排序!!! * *什么是位图?答:构建公式:bitmap[arr[i]]=1; 其中arr是我们的传统数组,bitmap是位图数组。 *位图长度多少?答:bitmap.length=arr[i].maxValue; 因为位图数组基于传统数组来构建,所以位图数组的长度等于传统数组的最大值+1。 *例如:现在存在传统数组{1,2,3,5,8} * 位图下标:0 1 2 3 4 5 6 7 8 * 对应的值:0 1 1 1 0 1 0 0 1 位图数组:{0,1,1,1,0,1,0,0,1} 再次考验 传统数组 {2,4,3,1,9999999} 对应位图数组 0 1 1 1 1 0 0 0 0 0 0 0 0 .....1 1个int=4Byte 1亿个数字int = 4亿B/1024/1024=370MB * * 为什么使用位图?答:直接从1亿数据里面找Top100效率很低,通过构建位图,然后倒序输出位图就可以快速找到Top100.或者TopN * * 需要耗费多少时间?答:构建位图+倒序输出 = 累计耗时 * * 从下面的测试结果我们可以看到,最耗时的是位图的构建过程. * 1.找最大值:14ms * 2.构建位图:149ms * 3.倒序输出:84ms * 4.累计耗时:234ms * * 总结:由此可见,位图排序,可以快速完成1亿数据的排序,顺序都排好了,拿Top100更是轻而易举的事。 * */ public class Test { public static int[] bitmapSort(int[] inputArray) { // 1.获取传统数组的最大值.即位图数组的长度 long findMaxBegin = System.currentTimeMillis(); int maxValue = inputArray[0]; for (int i = 0; i < inputArray.length; ++i) { if (maxValue < inputArray[i]) { maxValue = inputArray[i]; } } System.out.println("1.找最大值:" + (System.currentTimeMillis() - findMaxBegin) + "ms"); //2.将传统数组转换成位图数组 long bitmapBegin = System.currentTimeMillis(); byte[] bitmap = new byte[maxValue+1]; //bitmap[arr[i]]=1 for (int i = 0; i < inputArray.length; ++i) { bitmap[inputArray[i]] = 1; // 转换规则:传统数组的值就是位图数组的值需要置1的下标 } System.out.println("2.构建位图:" + (System.currentTimeMillis() - bitmapBegin) + "ms"); //3.倒序遍历位图 ,如果值为1则输出 . 相当于返回一个排序好的传统数组。 long descBegin = System.currentTimeMillis(); int[] result = new int[inputArray.length]; int index=0; for (int i = bitmap.length - 1; i >= 0& index < result.length; i--) { if (bitmap[i] == 1) { result[index++] = i; } } System.out.println("3.倒序输出:" + (System.currentTimeMillis() - descBegin) + "ms"); System.out.println("4.累计耗时:" + (System.currentTimeMillis() - findMaxBegin) + "ms"); return result; } public static void main(String[] args) { // 设置传统数组的长度 int inputArray[] = new int[10000000]; // 产生随机数的范围0~maxNum for (int i = 0; i < inputArray.length; ++i) { inputArray[i] = (int) (Math.random() * inputArray.length); } //获取Top100 int[] result = Test.bitmapSort(inputArray); for (int i = 0; i <100; i++) { System.out.print(result[i]+","); } } }
相关文章推荐
- [转]从1亿个数字中取出最大的100个
- 数据结构与算法——有1亿个整数,找出最大的1000个,要求时间越短越好,空间占用越少越好
- 算法兴趣----- 一亿数据获取前100个最大值(仅供参考,基于快速排序的实现时间不稳定,基于最小堆实现。如果我们只要求前K个最大(小)值的时候,用堆是最好的选择,因为这里不用每次都排序了)
- 数字排序 o(n)时间 o(1)空间
- 一串首尾相连的珠子(m个),有N种颜色(N《=10),设计一个算法,取出其中一段,要求包含所有N中颜色,并使长度最短。并分析时间复杂度与空间复杂度
- 腾讯面试题:一亿数字获取前100个最大的数字办法
- 题目:输入一个已经按升序排序过的数组和一个数字, 在数组中查找两个数,使得它们的和正好是输入的那个数字。 要求时间复杂度是O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。 例如输入数组1、2、4、7、11、15和数字15。由于4+11=15,
- 取出分组后每组的第一条记录(不用group by)按时间排序
- SQL取得最大排序数字并累加1的自定义函数
- 两个数组[n] [m] n>m 第一个数组的数字无序排列 第二个数组为空 取出第一个数组的最小值 放到第二个数组中第一个位置, 依次类推. 不能改变A数组,不能对之进行排序,也不可以倒到别的数组中。
- 数组排序数字大小,与筛选最大值最小值。冒泡比较法。。研究了好久才写出来与大家分享
- 相同的ID,按时间排序取最大的一个值怎么取
- 抛砖引玉&#8212;&#8212;实现LISTVIEW点击COLUMN排序的代码,可实现按时间,字符,数字
- ver[SIZE]保存的是[iBegin,iBegin+SIZE-1]区间的值,且无重复,请以O(N)时间复杂度和O(1)空间复杂度进行排序
- 阿里巴巴面试算法题目:有无序的实数列V[N],要求求里面大小相邻的实数的差的最大值,关键是要求线性空间和线性时间
- N个大小不等的自然数排序,时间复杂度为O(n),空间复杂度为O(1)
- 腾讯面试题:一亿数字获取前100个最大的数字办法
- 在线性时间和空间复杂度内,求大小相邻两元素之差的最大值
- 动态规划求数组中和最大字串的值 以及 字符串的循环移位(要求空间复杂度O(1),时间复杂度O(n))
- 阿里巴巴面试算法题目:有无序的实数列V[N],要求求里面大小相邻的实数的差的最大值,关键是要求线性空间和线性时间