LeetCode 1439. Find the Kth Smallest Sum of a Matrix With Sorted Rows

LeetCode 1439

求的是k个最小值,那么有一个可以考虑的方法就是维护一个堆,然后把最小的k-1一个pop掉。只是怎么来维护进堆的顺序。
因为每行都是已经排序的,第一个组合应该是取每行中的第一个,然后可以考虑把各行前进一格的放入堆中,取出最小的一个,然后再把隔行的下一个组合放入堆中。但是要考虑重复的情况。所以如果访问过了,我们就不再加入堆。

    def kthSmallest(self, mat: List[List[int]], k: int) -> int:
    	#维护一个最小堆
        minh = []
        #有m行
        m = len(mat)
        #n列
        n = len(mat[0])

        #当前每行取的位置,第一个组合,我们去的全部是第一个位置
        index = [0]*m

		#求出index所在的和
        def getSum(mat, index):
            total = 0
            m = 0
            for i in index:
                total += mat[m][i]
                m+=1
            return total

		#把index转为10进制数,方便加入set用于校验是否已经访问过
        def convert(index):
            ci = 0
            for i in index:
                ci = ci*10 + i                
            return ci

        visited = set()
        visited.add(convert(index))
        collections._heapq.heappush(minh, (getSum(mat, index), index))
        while k > 0 and len(minh) > 0:
            current = collections._heapq.heappop(minh)
            k -=1
            index = current[1]
            #移动其中的一行,加入堆
            for i in range(m):
                if index[i] == n-1:
                    continue
                ic = index.copy()
                ic[i] +=1
				#如果已经访问过,那么不再加入
                if convert(ic) in visited:
                    continue
                collections._heapq.heappush(minh, (getSum(mat, ic), ic))
                visited.add(convert(ic))

        return current[0]

这个方法思路比较简单,但是整体效率不高,因为我们还要做去重。

另外一个方法是利用:
https://blog.csdn.net/frankguodongchen/article/details/105760871
的结果,每次组合两行,求出最小的k个组合,然后继续和下一行进行组合。

    def kthSmallest(self, mat: List[List[int]], k: int) -> int:
        minh = []
        m = len(mat)
        n = len(mat[0])

        ans = mat[0]
        for m in mat[1:]:
            ans = self.kSmallestPairs(ans, m, k)
        return ans[k-1]

    def kSmallestPairs(self, nums1: List[int], nums2: List[int], k: int) -> List[List[int]]:
        if not nums1 or not nums2:
            return []
        M = len(nums1)
        N = len(nums2)
        heapSize = min(k, N)

        minHeap = [(nums1[0] + nums2[i], 0, i) for i in range(heapSize)]
        heapq.heapify(minHeap)
        
        result = []
        while minHeap and k > 0:
            val, r, c = heapq.heappop(minHeap)
            k -=1
            result.append(val)
            if (r < M-1):
                heapq.heappush(minHeap, (nums1[r+1] + nums2[c], r+1, c))
        return result  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值