使用QuickSelect

时间:2016-08-04 16:33:14

标签: python algorithm matrix

我知道之前已经问过这个问题,但这个问题与我的具体代码有关。我正在尝试使用伪造的QuickSelect算法,其中我将k与已排序矩阵的子区间的中点进行比较。

我一直收到超时错误。

这是矩阵:

matrix = [
   [ 1,  5,  9],
   [10, 11, 13],
   [12, 13, 15]
],
k = 8

这是我的代码:

def kthSmallest(self, matrix, k):
    """
    :type matrix: List[List[int]]
    :type k: int
    :rtype: int
    """

    return self.matrixRecur(matrix, (0, 0), (len(matrix) - 1, len(matrix[0]) - 1), k)

def matrixRecur(self, splicedMatrix, left, right, k):
    start_row, start_col = left
    end_row, end_col = right
    mid_row = (start_row + end_row)/2
    mid_col = (start_col + end_col)/2

    i = start_row
    j = start_col
    lcount = 0
    while(not (i == mid_row and j == mid_col)):
        if j < len(splicedMatrix[0]):
            j += 1
        else:
            j = 0
            i += 1
        lcount += 1
    if k == lcount:
       return splicedMatrix[mid_row][mid_col]
    elif k < lcount:
        return self.matrixRecur(splicedMatrix, (start_row, start_col), (mid_row, mid_col), k)
    else:
        return self.matrixRecur(splicedMatrix, (mid_row, mid_col + 1), (end_row, end_col), k-lcount)

我将元组传递给matrixRecur,其中包含间隔端点的(row, col)。所以,如果我想搜索整个矩阵,我会通过(0, 0)(n, n)matrixRecur将查看子区间,根据端点的行col编号确定中点,计算小于中点的元素数,将其与k进行比较。如果k小于小于中点(lcount)的元素数,则第k个最小元素在左边区间内,因为最多lcount个元素小于中点和k&lt; lcount

我在面试问题网站上运行这个,网站继续告诉我我的代码超时。我不明白为什么。

1 个答案:

答案 0 :(得分:0)

您的上述方法无效。因为您的矩阵按行和列进行排序。考虑下面的矩阵

10, 20, 30, 40
15, 25, 35, 45
24, 29, 37, 48
32, 33, 39, 50

在这种情况下,您的方法将失败。您正在抽出时间,因为您正在遍历整个2D矩阵。最差情况时间复杂度为O(mn)(m和n分别为行数和列数)。

您可以使用 min-heap 来解决此问题。

算法:

1. Build a min heap of first row elements. A heap entry also stores row number and column number.

2. for(int i=0;i<k;i++)
       Get minimum element (or root) from min heap.
       Find row number and column number of the minimum element.
       Replace root with the next element from same column and min-heapify the root.

3. Return the last extracted root.

时间复杂度:O(n + kLogn)

来源:Kth smallest in 2D matrix