完全排序的矩阵

时间:2010-10-31 21:12:49

标签: matrix

在我的一次求职面试中,我问过这个问题 -

M是2d n×n矩阵,其中每行和每列都被排序,并且所有矩阵元素都是不同的。我需要一个O(n)算法 - 给定索引i,j,i0,j0作为输入,计算M的元素数量小于M [i,j]并且大于M [i0,j0]。我为此尝试了各种方法,但无法弄清楚。将非常感谢帮助。接下来的部分是找出O(nlogn)预期时间内M的中位数。

1 个答案:

答案 0 :(得分:0)

将矩阵视为一组行。在每一行中都有最小和最大有效值的索引。如果您知道这些索引,则可以在O(1)中计算该行中的有效值的数量。 (通过有效,我的意思是M [i,j]和M [i0,j0]之间的值。)

现在,矩阵已排序。让我们采取下限:(i,j)。

  • 如果要查找上一行中最小有效值的索引,则必须位于(i,j)的右侧。这是因为正上方(i,j)必须存在无效(太小)的值。

  • 如果你想在下一行找到最小有效值的索引,它必须位于(i,j)的左侧(或它的正下方)。

因此,您需要在矩阵中最多走2n“步”以找到每行的下限索引。上限也是如此。所以你的步行是O(n),然后计算每一行的有效值数是O(n),因此总时间是O(n)。

使用此算法可以解决中位数问题。首先请注意,如果计算上一个问题的解,您可以使用每行中边界值的索引在线性时间中随机选择一个有效值。然后可以通过二分算法计算中位数:

selection_find(M, i0,j0, i2,j2, K):
    # Find K-th smallest number between M(i0,j0) and M(i2,j2)
    # assumption: M(i0,j0)<M(i2,j2)
    N := number of values between M(i0,j0) and M(i2,j2)
    # assumption: k<N
    Pick at random i1,j1 so that M(i0,j0)<M(i1,j1)<M(i2,j2)
    L := number of values between M(i0,j0) and M(i1,j1)
    if L==K:
        The answer is M(i1,j1)
    if L<K:
        The answer is selection_find(M, i1,j1, i2,j2, K-L)
    if L>K:
        The answer is selection_find(M, i0,j0, i1,j1, K)

median_find(M):
    The answer is selection_find(M, 1,1, n,n, n²/2)

每个步骤都需要O(N)。将有O(logN²)= O(2log N)= O(log N)步(每个步骤应将所考虑的值的数量减半)。因此,总复杂度为O(NlogN)。