【问题标题】:O(n) algorithm to find out the element appearing more than n/2 timesO(n) 算法找出出现超过 n/2 次的元素
【发布时间】:2010-12-21 03:25:48
【问题描述】:

我在一次采访中被要求给出一个 O(n) 算法来打印一个在数组中出现超过 n/2 次的元素,如果存在这样的元素。 n 是数组的大小。 我不知道如何做到这一点。有人可以帮忙吗?

【问题讨论】:

  • 您可以在扫描数组时只使用哈希并计算元素的数量吗?
  • 不确定。我认为应该有一个更简单优雅的解决方案。
  • 哦。你没有要求最优雅,只是 O(n)
  • @Samuel:这不是暗示吗?你本可以做得更糟;)
  • @sje397 好吧,听起来 OP 不知道如何在 O(n) 中做到这一点,或者不清楚这意味着什么,当“elagance”或涉及“最有效”:D

标签: c++


【解决方案1】:

这是Boyer's Voting algorithm

在太空中也是 O(1)!

编辑

对于那些抱怨网站配色方案的人(比如我)...here is the original paper

【讨论】:

  • 那个链接的配色方案太糟糕了。
  • 这里有更多信息:stackoverflow.com/questions/780937/…
  • 很好读。花了我一分钟时间找到避免维护独立计数的微妙逻辑:“..._increment or decrement the counter_ based on if e is the current candidate...”
  • @pst Boyer 在他的作品中有几个这样的微妙之处。例如他的字符串匹配算法。一颗宝石! en.wikipedia.org/wiki/…
  • 谢谢! @chrisaycock 该链接提供了丰富的信息。我也有类似的疑问。
【解决方案2】:

在伪代码中:

int n = array.length
Hash<elementType,int> hash
foreach element in array
    hash[element] += 1
foreach entry in hash
    if entry.value > n/2
        print entry.key
        break

【讨论】:

  • 这不会被认为是 O(2n) 吗?
  • @Eric 这将是O(n+m)。顺便说一句,没有 O(2n) 这样的东西,因为 big-O 不使用常数系数;在这种情况下,它只是O(n)
  • @chrisaycock。设mhash 中的条目数,narray 中的元素数。 m &lt;= n 所以假设没有哈希冲突,这个算法确实需要 O(n) 时间。 (如果我们允许哈希冲突,最坏的情况是 O(n^2) 时间。)
  • @chrisaycock - 有 O(2n) 这样的东西......它与 O(n) 相同。它仍然是一个有效的声明。
【解决方案3】:

它也是中值,使用median-of-medians algorithm 需要 O(n) 才能找到。在 C++ 中,您可以在一行中做到这一点:

std::nth_element(begin, begin + n/2, begin + n)

【讨论】:

  • 请注意,尽管 std::nth_element 只需要预期 O(n),因此很可能不使用中位数算法。在实践中,类似快速排序的选择往往比 m-of-m 更好。
猜你喜欢
  • 2014-03-24
  • 1970-01-01
  • 1970-01-01
  • 2014-04-30
  • 2020-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-01
相关资源
最近更新 更多