【问题标题】:find the value that was present maximum number of entries找到存在的最大条目数的值
【发布时间】:2016-02-19 18:01:32
【问题描述】:

我最近参加了一次采访。我被问到以下问题:

您有具有不同值的文本文件,每行一个。如何找到存在于最大行数/条目数中的一个值?

我给出了 hashmap 作为具有恒定时间复杂度的解决方案。

然后面试官换了个问题,问如果文件有100亿行怎么办?

现在我不能使用哈希图。我想不出办法。 任何人都可以提出一种方法。

有没有办法将相同的项目组合在一起?

【问题讨论】:

    标签: algorithm search


    【解决方案1】:

    您可以对文件进行排序,然后执行一次只需要 O(1) 内存的过程。

    【讨论】:

    • 如何对O(1)内存的文件进行排序?
    • 通行证需要 O(1) 内存。不管有多少可用的排序都可以使用,例如合并排序可以用临时文件很好地实现。
    【解决方案2】:

    如果值的范围限制为 32 位整数,一种简单的方法是保留一个 4GiB 的 8 位饱和计数器数组。

    • 在一次通过后,如果只有一个计数器达到 255,那么这就是重复次数最多的值。
    • 否则,记录所有饱和到 255 的计数器的值。
    • 再次遍历文件,仅更新 64 位计数器以获取您记录的值。 (忽略其他人)。

    您可以在运行中转换为使用更长的计数器,以使其成为一次性算法。 255 是计数器的标记值,这意味着您应该改为引用值的哈希图 -> 64 位计数器。

    如果 4GiB 太多,您可以使用 4 位饱和计数器,但是更多的计数器会饱和,它们的更新速度会更慢(尽管内存仍然是瓶颈,无论是否有额外的移位指令/mask/recombine-with-old-value)。

    使用多级方法没有意义(1 位饱和计数器,然后是 8 位饱和计数器,...),因为第一个之后的所有级别都必须是稀疏的(或者没有意义)。稀疏映射的每个条目开销,如哈希或树,将主导实际计数器的大小,因此为密集的第一级使用尽可能多的内存,然后回退到哈希映射二级64位计数器。


    如果密集的计数器数组根本不可行(例如长数字)

    在计算重复项时分批排序,然后合并这些批次。例如,请参阅我对Memory-constrained external sorting of strings, with duplicates combined&counted, on a critical server (billions of filenames) 的回答,以获取有关如何在批处理时最大化效率的建议。那是针对字符串,而不是整数,但是像Tries 这样的方法可以在运行中以良好的空间效率计算重复项,对于数字字符串比对任意字符串更有效。 Radix Trie(节点可以表示字符串,而不仅仅是字符)可能比这么小的字母表更麻烦。

    在任何情况下,如果要进行排序,请计算重复次数,直到您在编写批处理之前使用了尽可能多的可用内存。您在第一遍中找到并计数的每个重复项都是以后不必合并的。

    【讨论】:

      【解决方案3】:

      将所有值按照hashvalue分成若干个文件,然后对每个文件使用hashmap。

      而且,时间复杂度是O(n)而不是O(1)

      【讨论】:

      • 您可以根据前 2 位或前 3 位进行分桶,而不是浪费时间散列。
      • 你不明白这个问题。问题是:如何找到出现次数最多的值?就像1, 2, 3, 4, 5, 1, 4, 1一样,号码应该是1,因为有1
      • 不,你第一次看是对的。存在于最大行数中的值。 IE。重复次数最多的值。
      猜你喜欢
      • 2022-01-11
      • 2011-10-03
      • 1970-01-01
      • 1970-01-01
      • 2012-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-18
      相关资源
      最近更新 更多