Algorithm 查找前10个搜索词的算法

Algorithm 查找前10个搜索词的算法,algorithm,data-structures,Algorithm,Data Structures,我目前正在准备一次面试,这让我想起了我在上次面试中被问到的一个问题,类似这样: Time: 0 hours -Search Terms: -free stuff: 56 -funny pics: 321 -stackoverflow: 1234 Time: 1 hour -Search Terms: -ebay: 12 -funny pics: 1 -s

我目前正在准备一次面试,这让我想起了我在上次面试中被问到的一个问题,类似这样:

Time: 0 hours
      -Search Terms:
          -free stuff: 56
          -funny pics: 321
          -stackoverflow: 1234
Time: 1 hour
      -Search Terms:
          -ebay: 12
          -funny pics: 1
          -stackoverflow: 522
          -BP sucks: 92
“您被要求设计一些软件,以连续显示Google上的前10个搜索词。您可以访问一个提要,该提要提供当前在Google上搜索的无休止的实时搜索词流。请描述您将使用什么算法和数据结构来实现此目的。您将设计两种变体:

(i) 显示所有时间的前10个搜索词(即自您开始阅读提要以来)

(ii)仅显示上个月的前10个搜索词,每小时更新一次

您可以使用近似值获得前10名列表,但必须证明您的选择是正确的。”
我在这次采访中失败了,但仍然不知道如何实施

第一部分要求在无限列表的不断增长的子序列中查找10个最频繁的项。我研究了选择算法,但找不到任何在线版本来解决这个问题

第二部分使用一个有限的列表,但由于处理的数据量很大,您无法将整个月的搜索词存储在内存中,并每小时计算一次直方图

由于前十名列表不断更新,问题变得更加困难,因此您需要通过滑动窗口计算前十名


有什么想法吗?

将搜索词的计数存储在一个巨大的哈希表中,在这个哈希表中,每次新的搜索都会导致一个特定元素增加一个。跟踪前20个左右的搜索词;当第11位的元素递增时,检查它是否需要用#10*交换位置(无需保持前10位的排序;您所关心的只是在第10位和第11位之间画出区别)


*需要进行类似的检查,以查看新的搜索词是否位于第11位,因此此算法也会冒泡到其他搜索词——因此我将简化一点。

有时最好的答案是“我不知道”

我再深入一点。我的第一反应是将结果输入Q。a流程将持续处理进入Q的项目。该流程将维护

术语->计数

每次处理Q项时,只需查找搜索项并增加计数

同时,我将维护一个列表,列出地图中前10个条目的引用

对于当前实现的条目,请查看其计数是否大于前10名中最小条目的计数(如果尚未在列表中)。如果是,则用条目替换最小的条目

我想那会管用的。任何操作都不是时间密集型的。您必须找到一种方法来管理计数映射的大小。但这对于面试答案来说应该足够了

他们并不期待一个解决方案,他们想看看你是否能思考。你不必当场写出解决方案……

你可以使用a和a的组合。实现一个
字典,它告诉您每个搜索词被搜索了多少次

显然,每小时迭代整个哈希表以获得前10名是非常糟糕的。但我们谈论的是谷歌,所以你可以假设前十名都会获得,比如说超过10000次点击(尽管这可能是一个更大的数字)。因此,每当一个搜索词的计数超过10000时,将其插入BST。然后每小时,您只需从BST获取前10个,其中应包含相对较少的条目

这就解决了历史上排名前十的问题


真正棘手的部分是如何在月报中用一个词代替另一个词(例如,“stack overflow”在过去两个月可能有50000次点击,但在过去一个月只有10000次,而“amazon”在过去两个月可能有40000次点击,但在过去一个月有30000次点击。您希望“amazon”排在“stack overflow”之前吗在您的月度报告中)。为了做到这一点,我会为所有主要的(超过10000次的搜索)搜索词存储一个30天的列表,告诉你每天搜索该词的次数。这个列表就像一个FIFO队列:你每天(或每小时)删除第一天并插入一个新的,但是你可能需要存储更多的信息,这意味着更多的内存/空间。如果内存不是问题,就这样做,否则就按照他们说的“近似值”去做


这看起来是个好的开始。然后,你可以担心删减点击率超过10000次但在很长一段时间内没有多少点击率的术语,诸如此类

一种方法是,对于每次搜索,都存储该搜索词及其时间戳。这样,找到任何时间段的前十名只需比较给定时间段内的所有搜索词


算法很简单,但缺点是内存和时间消耗更大。

好吧,看起来数据太多了,存储所有频率的成本可能过高当数据量如此之大,以至于我们无法希望将其全部存储时,我们就进入了数据流算法领域

这方面的有用书籍:

与我从上面选择的问题密切相关的参考:

顺便说一下,斯坦福大学的莫特瓦尼(编辑)是这本非常重要的书的作者本书第11章论述了这个问题编辑:对不起,参考文献不正确,那一章是关于另一个问题的。检查后,我建议您在线购买

嘿,很好的面试问题

频率估计概述 有一些众所周知的算法可以使用固定的存储量为这样的流提供频率估计。一个是频繁的,由米斯拉和格里斯(1982年)。Fr
   for each record in sorted disk file
        update archive database by increasing frequency
        if rowcount == 0 then put the record into a list
   end for

   for each record in the list of having rowcount == 0
        insert into archive database
   end for
T a1 a2 a3 ... a-M T b1 b2 b3 ... b-M ...