在排序数组的并集中查找第k个最小元素

时间:2012-09-23 20:00:02

标签: python algorithm

我正在研究有关在leetcode找到两个排序数组联合中第k个最小元素的文章。我不认为算法是正确的。有这条线:我们观察到当Ai&lt; Bj,那么Ai&lt; BJ-1。另一方面,如果Bj <艾,然后Bj&lt; AI-1 即可。对于任何ij,情况如何?

其次,这一行也令我感到困惑:我们试图通过比较A和B的中间元素来解决这个棘手的问题,我们将其识别为Ai和Bj。如果Ai在Bj和Bj-1之间,我们刚刚找到了i + j + 1最小元素,尽管它是真实的。任何人都可以解释原因吗?我真的想要理解算法,我已经通过合并数组来完成它,但这需要O(N)时间,而O(log N)时间则需要{。}}。

2 个答案:

答案 0 :(得分:7)

你是孤立地解释这些陈述,但它们是相互依赖的。这是(我认为)你所指的文字:

  

维持不变量       i + j = k - 1,   如果Bj-1&lt; Ai&lt; Bj,然后艾必须是第k个最小的,   或者如果Ai-1&lt; Bj&lt;艾,然后Bj必须是第k个最小的。   如果满足上述条件之一,我们就完成了。如果没有,我们将使用i和j作为细分索引来细分数组。但是怎么样?我们应该丢弃哪部分?艾和Bj本身怎么样?

     

我们观察到当Ai&lt; Bj,那么Ai&lt; BJ-1。另一方面,如果Bj <艾,然后Bj&lt; AI-1。为什么呢?

将其分解为子命题会产生以下解释(请记住,索引从0开始,但A0第一个最小项,{ {1}}是第二个最小的项目,依此类推):

  1. A1(根据定义不变)
  2. 张贴i + j = k - 1。然后Bj-1 < Ai < Bj必须是Ai最小的k。这是因为Ai大于i中的A项,大于j中的B项。所以它总共大于i + j = k - 1个项目。这意味着合并的A|B列表中的 index 将为k - 1,因此它将是该列表中的k项。
  3. 张贴Ai-1 < Bj < Ai。然后Bj必须是k最小的,与2中的推理相同。
  4. 现在认为(a)Bj-1 < Ai < Bj和(b)Ai-1 < Bj < Ai都是 false 。然后很明显,如果Ai < Bj那么A1 < Bj-1,因为否则(a)将是真的。同样,如果Bj < AiBj < Ai-1,否则,(b)将成立。
  5. 我告诉你,你想要解释这些陈述而不是整个算法。 (但如果你愿意,我会说更多。)

    另请注意,正如Daniel Fischer的回答提醒我的那样,上述推理只有在没有重复的情况下才有效;称之为命题0.

答案 1 :(得分:4)

  

我们观察到Ai < Bj时,Ai < Bj-1必须为真。另一方面,如果Bj < Ai,则为Bj < Ai-1 ..对于任何ij,情况如何?

所有ij对都不是这样。本文考虑了一种特殊情况。

首先,假设没有重复,甚至没有AB的共同元素的形式。二,结论

Ai < Bj ==> Ai < Bj-1,   resp.  Bj < Ai ==> Bj < Ai-1

是在

的条件下制作的
Bj-1 < Ai < Bj  resp. Ai-1 < Bj < Ai

成立。因此,通过排除这些配置,Ai < Bj ==> Ai <= Bj-1Bj < Ai ==> Bj <= Ai-1会立即跟随,然后严格的不等式遵循不存在重复的假设。

  

我们试图通过比较A和B的中间元素来解决这个棘手的问题,我们将其识别为Ai和Bj。如果Ai在Bj和Bj-1之间,我们刚刚找到了i + j + 1个最小元素

在数组B中,有j个元素小于Bj,而在数组A中,有i个元素小于Ai }(索引从0开始)。因此,如果Bj-1 < Ai < Bj,则两个数组一起包含的j + i元素都小于Ai

如果有重复项会有什么变化?

不多。

我们仍然考虑i + j = k-1的情况。我们假设Ai <= Bj

  1. 如果Ai = Bj
  2. 怎么办?
  3. 如果Ai < Bj
  4. 怎么办?

    在案例1中,让m成为最小的索引,使Am = Ain成为Bn = Bj的最小索引。然后在两个数组中,确实有m + n <= i + j = k-1个元素严格小于Ai,并且至少(i+1) + (j+1) = (k+1)个元素不大于Ai。因此,第k个最小元素等于Ai

    对于2.,我们需要考虑三种情况,a)Bj-1 < Ai,b)Bj-1 = Ai,c)Bj-1 > Ai

    如果是a),我们在j中的B元素不大于Ai,并且它们都严格较小,并且我们有m <= i个元素A严格小于Aim如上)和未知数字,但至少i-m+1个元素等于Ai。因此,两个数组中的确切j + m <= j + i = k-1元素严格地小于Ai,并且至少j + m + (i-m+1) = j+i+1 = k元素不大于Ai,因此是第k个最小元素两个数组一起等于Ai

    在情况b)中,相同的推理表明两个数组的第k个最小元素一起等于Ai

    在剩下的情况下,Ai < Bj-1,事情变得不复杂了。数组B包含至少j个不大于Bj-1的元素,数组A包含至少i+1个元素,严格小于Bj-1,因此两个阵列的第k个最小元素在一起最多与Bj-1一样大。但它不能小于AiB最多包含小于j-1的{​​{1}}元素,因此两个数组最多包含Ai个小于i + (j-1) = k-2的元素{1}})。

    因此,我们仍然可以从数组Ai中删除Ai下方的部分,从数组A中删除Bj-1上方的部分,然后重复进行操作。

    所有改变的是,一些严格的不平等必须被弱的不平等所取代。

    代码(如果传递索引和长度而不是切片会更有效,但切片会产生更短的代码):

    B