鉴于40亿个数字,如何找到不在这40亿个数字中的数字?我们只有1GB的内存。
数字可以是非连续的。
如何在10MB内存中做同样的事情?
答案 0 :(得分:2)
假设这是一个例行程序,您只需运行一次,请使用可用内存量作为限制因素。将数字加载到数组中,最多可达到可用内存量。使用您喜欢的排序算法对数组进行排序。进行二进制搜索以查看值是否存在。如果它在那里,你已经完成了,如果没有,那么清除数组并开始从你离开的最后一个位置加载文件中的数字。重复此过程,直到找到匹配项或到达文件末尾。
例如,如果您使用1 GB并且数字大4个字节(例如,C#int),请将上部数组绑定为类似1024 ^ 3/4 = 268435456 * i(其中我是一些值< 1以确保我们留下一些剩余的内存用于其他进程)。填充数组,排序,检查,重复。
如果您只有10 MB可以使用,请将上限数组设置为1024 ^ 2 * 10/4 = 10485760 * i。
而且真的,现在我想到了,因为无论如何必须触及每一个值,你最好只扫描列表并省略排序。如果您希望将列表保存在有序集(最大为数组大小)以供以后处理,那么排序将很有用。在这种情况下,您还需要存储数组的大小,以便您可以依赖于每次连续运行它们的排序事实。
答案 1 :(得分:0)
嗯,假设我可以选择一个大于40亿数字中最大数字的数字:
set i = 0
for each number:
load the number into memory
set i = max(i, number + 1)
答案 2 :(得分:0)
找出一组数字的最大值(O(N)及时,恒定空间),而不在集合中的数字是max + 1.
这并不是一个非常具有挑战性的问题。找到不在集合中的最小自然数可能是一个更好的问题。
答案 3 :(得分:0)
如果问题是“列表中有40亿个随机数,现在选择一个不在列表中的新随机数。”然后我将合并排序列表以按顺序排列O(n lg n)。然后沿着列表向下按O(n)的顺序将当前元素与下一个元素进行比较。有点像...
MergeSort(thelist);
for(int i = 0; i < thelist.Length; i++)
{
if(thelist[i] + 1 == thelist[i+1])
{
//it's just a duplicate element
continue;
}
else if (thelist[i] + 1 != thelist[i+1])
{
Console.WriteLine("the number is {0}", thelist[i] + 1);
break;
}
答案 4 :(得分:-1)
考虑到OP问题的广泛性,人们可以冒险在那里有40亿个随机数,并且选择了另一个随机数,需要检查新数字是否已经在列表中。
如果是这种情况,一个简单的二进制搜索(考虑到数字是有序的)应该足够与O(logN)的比较时间。
答案 5 :(得分:-1)