Algorithm 给定40亿个数字,如何找到不在这40亿个数字中的数字?我们只有1GB的内存
给定40亿个数字,如何找到不在这40亿个数字中的数字?我们只有1GB的内存 这些数字可以是非连续的Algorithm 给定40亿个数字,如何找到不在这40亿个数字中的数字?我们只有1GB的内存,algorithm,Algorithm,给定40亿个数字,如何找到不在这40亿个数字中的数字?我们只有1GB的内存 这些数字可以是非连续的 如何在10MB内存中实现同样的功能?假设我可以选择一个大于40亿个数字中最大的一个: set i = 0 for each number: load the number into memory set i = max(i, number + 1) 在时间、恒定空间中查找一组数字的最大值,不在该组中的数字为max+1 我觉得这不是一个很有挑战性的问题。寻找不在集合中的最小自然数可
如何在10MB内存中实现同样的功能?假设我可以选择一个大于40亿个数字中最大的一个:
set i = 0
for each number:
load the number into memory
set i = max(i, number + 1)
在时间、恒定空间中查找一组数字的最大值,不在该组中的数字为max+1
我觉得这不是一个很有挑战性的问题。寻找不在集合中的最小自然数可能是一个更好的问题。考虑到OP问题的广泛性,我们可以冒险发现其中有40亿个随机数,并且选择了另一个随机数,需要检查列表中是否有新的数
如果是这样的话,一个简单的二进制搜索,考虑到数字是有序的,比较时间应该是OlogN。如果问题是列表中有40亿个随机数,现在选择一个不在列表中的新随机数。然后我会合并排序列表,将其按顺序放在lg 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;
}
假设这是一个只需运行一次的例程,请使用可用内存量作为限制因素。将数字加载到数组中,直到达到可用内存量为止。使用您喜欢的排序算法对数组进行排序。执行二进制搜索以查看该值是否存在。如果它在那里,那么就完成了,如果没有,那么清除数组并从文件中最后一个离开的位置开始加载数字。重复此过程,直到找到匹配项或到达文件末尾 例如,如果要处理1GB,并且数字是4字节大的,比如说C int,那么将数组上限设置为1024^3/4=268435456*i,其中i是小于1的某个值,以确保为其他进程保留一点内存。填充数组,排序,检查,重复 如果只有10 MB可使用,请将上限数组绑定为1024^2*10/4=10485760*i 事实上,现在我想起来了,因为排序无论如何都必须涉及到每一个值,所以最好只扫描列表并忽略排序。不过,如果您希望将列表以有序的方式保存到数组的大小,以便以后处理,则排序将非常有用。在这种情况下,您还需要存储数组的大小,这样您就可以根据每个连续运行对数组进行排序的事实来确定它们的大小 后藤。 选择一个空间复杂度为1的算法。也许选择一个模糊的,这样你就可以看起来像一个真正的算法爱好者。如果你想让自己看起来像一个团队成员,也可以选择每个人都听说过的流行歌曲。 记住伪代码,并假装你已经记住了所有的排序算法,因为这是你为了好玩而在面试中炫耀的事情。 利润
这4个十亿元的数字是在哪里给出的?一分贝?档案?阵列?网络数字在哪里?如果数字是连续的就不太难了,如果不是,就更难了。我认为问题的目的是给定的数字在这个范围内随机分布,例如,我们有900个数字在1到1000之间。我们如何利用100多个存储空间最有效地解决这一问题?而你如何解决它只需要几个数字的存储。仅仅取一个最大值可能不会产生一个答案,因为集合中可能有1000个。@Abius:我想我们可以假设这些都在磁盘上,因为我们有限制RAM@rsbarro:不,数字绝对不是连续的,否则是不连续的,但是如果40亿数字已经包含了MAX_值和MIN_值,然后我们需要找到小于MAX_值且大于MIN_值的数字,因为它应该适合整数范围。他们问的是“整数”,你怎么看?我想他的意思是集合中可能有17、4、6、10、15,你如何确定12是否不在集合中。我把这个问题理解为列表中40多亿个随机数,选择另一个不在列表中的随机数。但是你可能是对的。@jb如果是这样的话,如果数字是有序的,那就更容易了,只需从第一个搜索到最后一个,检查数字之间的差异。当然,这是可行的,因为我们都假设我们在处理自然数。如果我们冒险研究实数,那么事情就会变得非常糟糕,因为在1和2之间有无限的数字。需求是内存而不是时间。在最坏的情况下,空间复杂度是开的,就像在坏malloc中一样。@nate,不管怎样,如果我们要讨论内存分配的话,没有提到数字的大小。。。是字节吗?Int16?Int32?Int64?如今,多亏了托管语言和O.S,我们不需要太担心内存分配,因为
分页已经为我们完成了。然而,这种方法仍然存在。搜索40亿或10亿,算法是一样的。唯一改变的是向量在内存中的加载方式。我们需要自己分配还是让O.S.为我们分配?@nate,O.P.这个问题太离奇了,无法准确回答。数据的大小是多少?处理器是8位、16位、32位还是64位?分页为我们完成了吗?号码首先存储在哪里?在将约束仅放在内存中之前,有很多问题需要回答。