leetcode378.有序矩阵中第K小的元素

378.有序矩阵中第K小的元素(中等)

给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素。
请注意,它是排序后的第k小元素,而不是第k个元素。

示例:

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

返回 13。

说明:

你可以假设 k 的值永远是有效的, 1 ≤ k ≤ n^2 。

解法一:

用二分法,high是右下角,low是左上角,每次遍历矩阵,看小于等于mid的数count是多少,如果count<k,说明这个数在[mid+1,high]之间,如果count>=k,说明这个数在[low,mid]之间,最后当low==high时,就是第k小的元素。

class Solution(object):
    def kthSmallest(self, matrix, k):
        """
        :type matrix: List[List[int]]
        :type k: int
        :rtype: int
        """
        def counter(target, n):
            i = 0
            j = n-1
            count = 0
            while i<n and j>=0:
                if matrix[i][j] <= target:
                    count += j+1 #从右上角开始遍历如果它小了,那么它左边所有的都小
                    i += 1
                else:
                    j -= 1
            return count
        n = len(matrix)
        low = matrix[0][0]
        high = matrix[n-1][n-1]
        while low < high:
            mid = low + (high - low)//2
            count = counter(mid, n)
            if count < k:
                low = mid+1
            else:
                high = mid
        return low

解法二:

把n行矩阵看成n个递增的有序数组,可以设置n个指针,指向每个数组的第一个元素,把最小的取出来,之后那个指针加一,但是每次N个取最小,时间复杂度需要O(N),有没有更小的复杂度?
堆或优先队列不就是解决这种问题的方案嘛。维护一个N大小的最小堆,这样每次pop最小的,只需要logN。

所以维护一个最小堆,把每个数组目前最小的元素放到最小堆里,依次pop出来,之后Push它后面的那个元素,第k个pop的就是所求,注意当某一行pop完了之后就不需要push操作了。

class Solution(object):
    def kthSmallest(self, matrix, k):
        """
        :type matrix: List[List[int]]
        :type k: int
        :rtype: int
        """
        import heapq
        n = len(matrix)
        heap = []
        heapq.heapify(heap)
        for i in range(min(k, n)):
            heapq.heappush(heap, (matrix[i][0], i, 0))
        counter = 0
        x, i, j = 0, 0, 0
        while counter<k:
            counter += 1
            x, i, j = heapq.heappop(heap)
            if j<n-1:
                # 如果j大于等于n-1了,说明这一行都已经遍历完了,直接从剩下的里面继续弹出就好了。
                heapq.heappush(heap, (matrix[i][j+1], i, j+1))
        return x
        
Zo2
发布了20 篇原创文章 · 获赞 7 · 访问量 2263

猜你喜欢

转载自blog.csdn.net/weixin_43914692/article/details/101470777
今日推荐