【问题标题】:Given 4 billion numbers, how to find a number which is not in these 4 billion numbers? We have only 1GB of memory [duplicate]给定 40 亿个数字,如何找到不在这 40 亿个数字中的数字?我们只有 1GB 的内存 [重复]
【发布时间】:2011-07-15 11:30:09
【问题描述】:

给定 40 亿个数字,如何找到一个不在这 40 亿个数字中的数字?我们只有 1GB 的内存。

数字可以不连续。

如何在 10MB 内存中做同样的事情?

【问题讨论】:

  • 这 40 亿个数字在哪里给出?数据库?一份文件?数组?网络?在哪里
  • 数字是连续的吗?如果数字是连续的,这并不太难,如果不是,那就更难了。
  • 我认为问题的意图是给定的数字在范围内随机分布,例如。我们有 1 到 1000 范围内的 900 个数字。我们如何用 100 个数字的存储量最有效地解决这个问题?以及如何仅用少量存储来解决它。只取一个 max() 可能不会产生答案,因为集合中可能有 1000 个。
  • @Abius:我想我们可以假设它们在磁盘上,因为我们有 RAM 的限制
  • @rsbarro: 不,数字绝对不是连续的,否则它是微不足道的

标签: algorithm


【解决方案1】:
  • 转到http://en.wikipedia.org/wiki/Sorting_algorithm
  • 选择空间复杂度为1的算法。也许选择一个不起眼的,这样你就可以看起来像一个真正的算法爱好者。如果您想看起来像团队合作者,或者选择每个人都听说过的流行的。
  • 记住伪代码并假装你已经记住了每个排序算法,因为这是你为了好玩在面试中炫耀的。
  • 利润。

【讨论】:

    【解决方案2】:

    假设这是一个您只需要运行一次的例程,请使用可用内存量作为限制因素。将数字加载到数组中,直至您可用的内存量。使用您喜欢的排序算法对数组进行排序。进行二分搜索以查看该值是否存在。如果它在那里,你就完成了,如果没有,那么清除数组并开始从你上次离开的文件中加载数字。重复该过程,直到找到匹配项或到达文件末尾。

    例如,如果您有 1 GB 的空间可以使用,并且数字是 4 字节大(例如,C# int),则将数组上限设置为 1024 ^ 3 / 4 = 268435456 * i(其中 i 是一些value

    如果您只有 10 MB 可用,请将上限数组设置为 1024 ^ 2 * 10 / 4 = 10485760 * i。

    实际上,现在我想起来了,因为无论如何排序都必须触及每个值,所以最好只扫描列表并忽略排序。但是,如果您想将列表保存在有序集中(最多为数组的大小)以供以后处理,则排序将很有用。在这种情况下,您还需要存储数组的大小,这样您就可以依赖于它们在每次连续运行时都被排序的事实。

    【讨论】:

      【解决方案3】:

      考虑到 OP 问题的广泛性,可以冒险假设其中有 40 亿个随机数,然后选择另一个随机数,需要检查该新数字是否已经在列表中。

      如果是这种情况,一个简单的二分搜索(考虑到数字是有序的)应该足以满足 O(logN) 的比较时间。

      【讨论】:

      • 我把这个问题读成一个列表中有超过 40 亿个随机数,选择另一个不在列表中的随机数。但你可能是对的。
      • @jb 如果是这样的话,如果数字是有序的,那就更容易了,只需从第一个到最后一个检查数字之间的差异。当然这是可行的,因为我们都假设我们正在处理自然数字。如果我们冒险研究 REAL 数字,那么事情就会变得非常糟糕,因为在 1 和 2 之间有无限的数字。
      • 要求是内存而不是时间。最坏情况下的空间复杂度是 O(n),就像在 bad malloc 中一样。
      • @nate,不管怎样,如果我们要讨论内存分配,没有提到数字的大小......它是字节吗? 16?整数32?整数64?如今,多亏了托管语言和操作系统。我们不需要太担心内存分配,因为分页已经为我们完成了。但是,方法仍然存在。搜索 40 亿或 10 的算法是相同的。唯一改变的是向量在内存中的加载方式。我们需要自己分配还是让操作系统来分配?为我们做吗?
      • @nate,OP 的问题太笼统,无法准确回答。数据的大小是多少?处理器是 8 位、16 位、32 位还是 64 位?分页是否为我们完成?首先存储的数字在哪里?在将约束仅放在内存中之前,有很多问题需要回答。
      【解决方案4】:

      如果问题是“列表中有 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;
        }
      

      【讨论】:

        【解决方案5】:

        求这组数的最大值(O(N)在时间,常数空间),不在组内的数是max+1。

        这对我来说并不是一个非常具有挑战性的问题。寻找不在集合中的最小自然数可能是一个更好的问题。

        【讨论】:

        • 我认为他的意思是集合中可能有 17、4、6、10、15,您如何确定 12 是否不在集合中。
        【解决方案6】:

        好吧,假设我可以选择一个大于 40 亿个数字中的最大值的数字:

        set i = 0
        for each number:
            load the number into memory
            set i = max(i, number + 1)
        

        【讨论】:

        • 但是如果这 40 亿个数字已经包含了 MAX_VALUE 和 MIN_VALUE,那么我们需要找到小于 MAX_VALUE 和大于 MIN_VALUE 的数字,因为它应该在整数范围内。他们要求“整数”,你怎么看?
        猜你喜欢
        • 2015-03-12
        • 2012-04-27
        • 2014-05-11
        • 2011-11-01
        • 2020-08-14
        • 2016-01-08
        • 2020-07-01
        • 1970-01-01
        相关资源
        最近更新 更多