【问题标题】:Completely Sorted matrix完全排序矩阵
【发布时间】:2010-10-31 21:12:49
【问题描述】:

在我的一次工作面试中被问到这个问题 -

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

【问题讨论】:

    标签: matrix


    【解决方案1】:

    将矩阵视为一组行。在每一行中都有最小和最大有效值的索引。如果您知道这些索引,则可以在 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(log N²)=O(2log N)=O(log N) 步骤(每个步骤应将考虑的值减半)。因此总复杂度为 O(NlogN)。

    【讨论】:

    • 请检查if L&gt;K: The answer is selection_find(M, i0,j0, i1,j1, K)这行是否应该是if L&gt;K: The answer is selection_find(M, i0,j0, i1,j1, L-K)?一位声望低的用户对此有所了解。
    • @nhahtdh:哦,谢谢你的留言,我会错过的。是的,我看到了 Michel 的回答,我认为他弄错了,虽然我现在有点头晕,我不确定。问题是,这种情况是我们的随机拍摄走得太远:我们知道(下限)
    猜你喜欢
    • 1970-01-01
    • 2022-12-22
    • 1970-01-01
    • 2014-06-02
    • 2020-11-04
    • 2010-09-14
    • 2022-08-17
    • 1970-01-01
    • 2018-03-15
    相关资源
    最近更新 更多