编程珠玑--位图法排序

简介: 题目:一个最多包含n个正整数的文件,每个数都小于n,其中n=10^7,且所有正整数都不重复。求如何将这n个正整数升序排列。
题目:一个最多包含n个正整数的文件,每个数都小于n,其中n=10^7,且所有正整数都不重复。求如何将这n个正整数升序排列。
约束:最多有1MB的内存空间可用,有充足的磁盘存储空间。
 
分析:这个题目的最大亮点是只有1MB的内存空间,我们可以通过计算得出,内存只有1MB可以储存的int(4byte)有10^3*10^3/4=250 000个号码。而包含正整数的文件约为10^7个int大小。这意味着无法将所有文件中的正整数一次读取进入到内存空间中去进行排序算法。因此衍生出下面两种方法:
方法2(位图法):
我们想使用hash映射,将对应的正整数映射到位图集合中。即将正整数映射到bit集合中,每一个bit代表其映射的正整数是否存在。
比如{1,2,3,5,8,13}使用下列集合表示:
0 1 1 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0
我们可以使用具有10^7位的字符串来表示这个文件。其中,当且仅当整数i在文件中存在时候,第i位为1
 
位图法方法:
  1. 创建有个10^7位(10^7/8/4≈1MB)的字符串,并将其每一bit设置为0;
  2. 读取包含正整数的文件,对每一个i,将内存中bit 位设置成1.
  3. 按位顺序读取字符串。当读取到bit[j] 为1时输出(int)j。
 
根据位图法演变解决以下QQ面试题目:
40 亿个不重复的 unsigned int 的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那 40 亿个数当中
 
unsign int范围为0~2^32-1(4294967295≈5*10^9) 使用位图hash对应5*10^9/8/10^3/10^3 = 625MB.
  1. 我们使用625M的字符串。每一位设置为0.
  2. 将40亿个unsign int 遍历一遍。使用位图法将字符串中的对应位转化为1。
  3. 读取“再给一个数i” 查看bit 是否为1,1则有存在,0则不存在。
目录
相关文章
|
27天前
|
索引
Leetcode第三十三题(搜索旋转排序数组)
这篇文章介绍了解决LeetCode第33题“搜索旋转排序数组”的方法,该问题要求在旋转过的升序数组中找到给定目标值的索引,如果存在则返回索引,否则返回-1,文章提供了一个时间复杂度为O(logn)的二分搜索算法实现。
16 0
Leetcode第三十三题(搜索旋转排序数组)
|
6月前
|
存储 机器学习/深度学习 人工智能
【408数据结构与算法】—数组和特殊矩阵的压缩存储(二十五)
【408数据结构与算法】—数组和特殊矩阵的压缩存储(二十五)
|
算法
【算法挨揍日记】day10——704. 二分查找、34. 在排序数组中查找元素的第一个和最后一个位置
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
362 0
|
索引
力扣34在排序数组中查找元素的第一个和最后一个位置:思路分析+图文详解+代码实现(最靠左索引,最靠右索引)
力扣34在排序数组中查找元素的第一个和最后一个位置:思路分析+图文详解+代码实现(最靠左索引,最靠右索引)
57 0
|
C++ 容器
【C++进阶】十一、哈希的应用---位图(一)
目录 一、位图的引入 二、位图的应用 三、位图的使用(bitset的使用) 3.1 介绍 3.2 使用 四、bitset(位图模拟实现)
146 0
【C++进阶】十一、哈希的应用---位图(一)
数据结构 --- 超全的排序总结--八大排序,动态图,代码
数据结构 --- 超全的排序总结--八大排序,动态图,代码
103 0
数据结构 --- 超全的排序总结--八大排序,动态图,代码
|
机器学习/深度学习 算法
LeetCode算法小抄--数组各种花式遍历技巧
LeetCode算法小抄--数组各种花式遍历技巧
|
SQL 搜索推荐 关系型数据库
B+树索引使用(8)排序使用及其注意事项(二十)
B+树索引使用(8)排序使用及其注意事项(二十)
|
存储 数据采集 缓存
数据结构与算法必知--- Bitmap位图与布隆过滤器
数据结构与算法必知--- Bitmap位图与布隆过滤器
【区间求和の解决方案】307. 区域和检索 - 数组可修改 :「树状数组」&「线段树」
【区间求和の解决方案】307. 区域和检索 - 数组可修改 :「树状数组」&「线段树」