【问题标题】:I have 2 sorted arrays of integers, how do I find the kth biggest item in O(logn) time? [duplicate]我有 2 个排序的整数数组,如何在 O(logn) 时间内找到第 k 个最大的项目? [复制]
【发布时间】:2014-03-24 19:46:56
【问题描述】:

我在一次采访中被问到这个问题。显然,我能够在 O(n) 时间内完成,但我没有想到一种在 O(logn) 中解决的方法。听起来像是在使用一些分而治之的算法,但我不确定。

【问题讨论】:

  • 你能提供你在 O(n) 中是怎么做的吗?你在两者之间来回跳跃?
  • 坦率地说,我看不出它怎么会小于 O(k):您比较两个数组的最后一个元素,并减少与两个项目中最大的数组关联的索引.这样做 k 次,你就有了第 k 个最大的元素。

标签: java algorithm sorting


【解决方案1】:

将两者都截断为大小 k。如有必要,让程序在一个或两个数组的末尾想象足够的无穷大,以使它们的大小达到 k;这不会影响渐近运行时间。 (在实际实现中,我们可能会做一些更有效的事情。)

然后,比较每个数组的第 k/2 个元素。如果元素比较相等,我们就找到了第 k 个元素;否则,让具有较低第 k/2 个元素的数组为 A,另一个为 B。丢掉 A 的下半部分和 B 的上半部分,然后递归地找到剩余的第 k/2 个元素。当我们达到 k=1 时停止。

每一步,保证A的下半部分太小,B的上半部分保证太大。剩下的第k/2个元素保证大于A的下半部分,所以保证是原来的第k个元素。

概念证明,在 Python 中:

def kth(array1, array2, k):
    # Basic proof of concept. This doesn't handle a bunch of edge cases
    # that a real implementation should handle.
    # Limitations:
    #   Requires numpy arrays for efficient slicing.
    #   Requires k to be a power of 2
    #   Requires array1 and array2 to be of length exactly k
    if k == 1:
        return min(array1[0], array2[0])
    mid = k//2 - 1
    if array1[mid] > array2[mid]:
        array1, array2 = array2, array1
    return kth(array1[k//2:], array2[:k//2], k//2)

我已经测试过了,但不多。

【讨论】:

  • 听起来像。 +1。
  • 如果元素比较相等,任意选择:如果两者相等,你没有找到第k大元素吗?
  • @JBNizet:我认为你是对的。
  • 我正在尝试实现此算法,但我似乎找到了该算法失败的案例。考虑数组A = {1}B = {2, 3} 并尝试找到第二大元素(应该是2)。当您将 A 尺寸设为 2 A = {1, ∞} 时,将其划分为中心 {1 | ∞} 然后删除 A 的右半部分和 B 的左半部分,剩下的是 A = {1}B = {3},其最小值为 1。
  • @user2612743:可能是 indexing-from-0 与 indexing-from-1 的问题。我的描述似乎从 1 开始索引。您应该删除 A 的左半部分和 B 的右半部分,而不是相反。
猜你喜欢
  • 2013-09-12
  • 2020-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多