【问题标题】:Design and analyze a linear time algorithm [closed]设计和分析线性时间算法 [关闭]
【发布时间】:2012-11-12 14:54:21
【问题描述】:

设计和分析一个线性时间算法以确定是否 在 n 个元素的列表中存在一个重复自身的元素 列表中至少出现 n/10 次。

我该怎么做?我将发布我自己的想法作为答案。

【问题讨论】:

  • 我假设您不是在寻找平均情况线性时间算法(带有额外的O(n) 空间)?如果是这样 - 可以通过创建基于元素的 histogram 哈希然后迭代直方图来完成。
  • @amit 请检查我的解决方案是否正确,谢谢。

标签: algorithm linear-search


【解决方案1】:

我假设这些元素是可比较的。

对以下第 n/10、2n/10、...、第 9n/10、第 10(n/10) 个最小元素执行 selection algorithm1

这些是你的候选人。检查每一个的#occurrences,如果其中一个重复至少 n/10 次,则答案是true。否则为false

证明:
如果一个元素至少出现 n/10 次,那么它必须与 k*n/10“相交”,以获得一些 k(在排序列表中)2。因此,该元素将被选为“候选”,您稍后会发现(通过计算)它出现的确切次数,并返回true

如果没有元素重复n/10 次,算法将在检查每个候选者的最后一步中简单地返回false

复杂性
每个选择算法都是O(n),做了10次。此外,对于每个候选人,都需要对列表进行线性扫描,这也是 O(n) 总计在 O(n) 中,但常数很糟糕。


解释

(1) 选择算法会在排序列表中找到索引n/10, 2n/10,...9n/10 中的元素,算法本身只有O(n)

(2)我们来看[1,2,..,100,100,..,100]的例子(11乘以100)。
请注意,列表已排序,元素 100 出现在:list[9*n/10](索引9*n/10)中。选择算法的思想是——即使你打乱了列表——select(list,9*n/10) 将总是返回相同的元素——在本例中为 100——因为它是排序列表中的第 9n/10th 元素(这就是算法)。

现在,您可以看到对于重复 n/10 次的每个元素(假设为 e),都有一些索引 i,这样在列表的排序版本中,索引中的所有元素 @987654341 @ 将是 e。对于某些k,这些索引之一必须k*n/10 之一(说服自己为什么!)。因此,k*n/10 上的选择算法将产生e

【讨论】:

  • 感谢您的解决方案,但请您稍微解释一下“如果一个元素至少出现 n/10 次,那么它必须与 k*n/10 “相交”一些 k (在排序列表中)。”仍然不太明白。为了让问题简单,我们假设列表中的元素都是整数。
  • @starcaller:我编辑了答案(参见编辑,尤其是第 2 节)。希望对您有所帮助。
  • @amit 但是如果我们有一个未排序的列表怎么办。
  • 迂腐提示:这个(非常好的)解决方案假设所寻找的元素必须在列表中出现超过n/10 次。如果它也可以恰好出现n/10 次,则k*n/10 点可能会错过它。然后使用k*n/11 进行选择。
  • @DanielFischer:你是对的,我首先虽然我们正在寻找 more then n/10 - 但从第二次阅读来看,情况似乎并非如此。编辑也检查第一个和最后一个元素。
【解决方案2】:

让我告诉你一个聪明的单程算法来找到一个多数元素(一个频率高于 n/2 的元素),你应该看看如何适应它:

best = null
count = 0

foreach x in list:
   if (count == 0)
      count++
      best = x
   else if (best == x)
      count++
   else
      count--

return best

如果存在多数元素,上述算法将找到它(一次通过,恒定空间)。一旦你弄清楚它是如何工作的,你就会看到它如何适应 n/10 的情况。

【讨论】:

    【解决方案3】:

    我的解决方案是将列表分成 10/n 个组,每个组包含 10 个元素,然后对每个组执行随机选择排序,这将花费 O(1)*O(n) 时间,即O(n)。

    由于要满足要求,候选元素必须在 n/10 组中的每一个中显示,我们可以对第一组中的 10 个元素中的每一个进行扫描,这将花费 10*O(n) 时间.

    所以算法的总时间是O(n)+10*O(n),还是O(n)。

    但如果组中的元素如下所示,这将不起作用:

    1,2,3,4,5,6,7,8,9,10
    11,11,11,11,11,11,11,11,11,11
    ...
    11,11,11,11,11,11,11,11,11,11
    

    我的算法将返回不存在这样的元素,而实际上 11 是出现超过 n/10 次的元素。

    【讨论】:

    • 您声称“候选元素必须在 n/10 个组中的每个组中显示”,但它可能会在某些组中丢失并在其他组中出现多次。另外我认为您的意思是“n/10 组”,而不是“10/n 组”。
    • the candidate element has to show in each of the n/10 groups 为什么?列表[1,2,...,100,100,100,....,100] 怎么样(11 乘以 100)。 100 不会出现在所有列表中,只会出现在最后 2 个列表中
    • @amit haha​​,刚刚编辑了我的解决方案。是的,这是让我思考了很长时间的棘手部分,知道如何让我的解决方案发挥作用吗?谢谢
    • @starcaller:(1)我试图添加我的解决方案作为答案。 (2) 你的答案是错误的 - 所以它可能会被否决。如果您希望它作为问题的一部分 - 您应该在问题本身中编辑并添加它 - 而不是作为独立答案。
    猜你喜欢
    • 2017-07-24
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    • 2018-09-03
    相关资源
    最近更新 更多