【问题标题】:kth smallest number第 k 个最小的数
【发布时间】:2016-09-25 08:50:51
【问题描述】:

假设我们有 n (1unique 组合中选出第 kth 个最小整数。有没有一种有效的方法来做到这一点,其复杂度低于 O(A1 + A2.. + An)?

可以解决类似二分查找的问题吗?

PS:我在这里有一个similar problem,但不明白如何为独特元素扩展它。

编辑 1: 我认为你们中的一些人误解了这个问题。让我们举个例子: N = 3,

A1 = 1、1、2、3

A2 = 6、7、9

A3 = 1、6、8

上述数组的唯一组合是{1, 2, 3, 6, 7, 8, 9}。现在假设我想要第 2 个元素它应该返回 2,而第 4 个元素它应该返回 6。

【问题讨论】:

  • 我不确定第 k 个最小唯一整数是什么意思,它不能在多个数组中重复?非唯一性是否算“较小”?例如 [1,2,3,4,5], [2,3] k=3 的输出是什么?
  • 寻找未排序条目的快速选择算法。对于排序数组,尝试寻找最小/最大堆
  • 数字在哪个范围内?
  • 数字在 0 到 10^9 的范围内,但它们也可以进行坐标压缩。

标签: algorithm binary-search


【解决方案1】:

可以在O(k n log n):

  • 用每个数组中的最小元素创建一个最小堆。
  • 重复k 次:
    • 查看最小堆中的最小元素q 并记住它
    • 从最小堆中提取,而最小值等于q
    • 对于每个提取的元素,从对应的数组中放入大于q的第一个元素
  • 答案是最小堆中的最小元素

Python 代码:

import heapq
import bisect

def kth(A, k):
    h = []

    for idx,a in enumerate(A):
        if len(a) > 0:
            heapq.heappush(h, (a[0], idx))

    for i in xrange(k):
        if len(h) == 0:
            return None

        val, _ = h[0]

        while (len(h) > 0) and (h[0][0] == val):
            _, idx = heapq.heappop(h)
            nxt = bisect.bisect_right(A[idx], val)
            if nxt < len(A[idx]):
                heapq.heappush(h, (A[idx][nxt], idx))

    if len(h) > 0:
        return h[0][0]
    return None

【讨论】:

    【解决方案2】:

    是否有空间要求,或者数组中的数字可以重复吗?

    如果没有,您可以创建 2 个排序集:uniques 和 nonUniques。 添加数组时,循环遍历数组并将其数字添加到 2 个排序集中,如下所示:

    • 如果 nonUniques 中存在新数字,则跳过它
    • 如果一个数字存在于 uniques 中,将其从 uniques 中删除并将其添加到 nonUniques
    • 否则将 nww 编号添加到唯一性

    然后你可以立即在排序的唯一集合中查找第 k 个最小的数字。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-13
      • 1970-01-01
      • 1970-01-01
      • 2019-04-11
      • 2014-03-16
      • 2012-10-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多