8

【LeetCode】matrix相关题目

 2 years ago
source link: https://www.guofei.site/2022/04/03/lc-matrix.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

59. Spiral Matrix II

复用 Spiral Matrix I 那个题

  • 先用一个矩阵填入连续数字
  • 然后展开它,以此确定展开顺序,并记下来
  • 按照上一步计算好的展开顺序,对结果矩阵填充
class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        matrix=[list(range(i*n,(i+1)*n)) for i in range(n)]


        matrix_copy=matrix.copy()
        spiral=[]
        while matrix_copy:
            spiral.extend(matrix_copy.pop(0))
            matrix_copy=list(zip(*matrix_copy))[::-1]

        helper=dict(zip(spiral,range(1,n*n+1)))

        for i in range(n):
            for j in range(n):
                matrix[i][j]=helper[matrix[i][j]]


        return matrix

顺着旋转的思路,可以进一步简化代码

class Solution:
    def generateMatrix(self, n: int):
        res, lo = [], n * n + 1
        while lo > 1:
            lo, hi = lo - len(res), lo
            res = [list(range(lo, hi))] + [list(line) for line in zip(*res[::-1])]
        return res

73. Set Matrix Zeroes

class Solution:
    def setZeroes(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        rows=[all(line) for line in matrix]
        cols=[all(col) for col in zip(*matrix)]
        len_rows,len_cols=len(rows),len(cols)


        for idx,col in enumerate(cols):
            if col==0:
                for i in range(len_rows):
                    matrix[i][idx]=0

        for idx,row in enumerate(rows):
            if row==0:
                matrix[idx]=[0]*len_cols

756. Pyramid Transition Matrix

只需要求出1个,所以用dfs

import collections

class Solution:

    def pyramidTransition(self, bottom: str, allowed: List[str]) -> bool:
        bricks=collections.defaultdict(list)

        for brick in allowed:
            bricks[brick[:2]].append(brick[2])
        res=[False]

        def pyramid_once(bottom):
            if len(bottom)==2:
                if bricks[bottom]:
                    res[0]=True
                return

            next_bottoms=['']
            for idx in range(len(bottom)-1):
                if bottom[idx:idx+2] not in bricks:
                    return

                next_bottoms=[next_bottom+i for i in bricks[bottom[idx:idx+2]]
                for next_bottom in next_bottoms
                ]


            for next_bottom in next_bottoms:
                if res[0]:
                    return
                pyramid_once(next_bottom)


        pyramid_once(bottom)
        return res[0]

766. Toeplitz Matrix

矩阵基础题。存储每个斜线的情况即可,也可以用位存储。

class Solution:
    def isToeplitzMatrix(self, matrix: List[List[int]]) -> bool:
        m,n=len(matrix),len(matrix[0])
        val=[None]*(m+n-1)
        for i in range(m):
            for j in range(n):
                if val[j-i+m-1] is None:
                    val[j-i+m-1]=matrix[i][j]
                else:
                    if  val[j-i+m-1]!=matrix[i][j]:
                        return False
        return True

867. Transpose Matrix

return list(zip(*matrix))

542. 01 Matrix

  • f(i,j) 定义为 i,j 到 0 的最近距离
  • 如果 matrix[i][j]=0,那么 f(i,j) = 0
  • 否则 f(i,j)=min(f(i-1,j) ,f(i,j-1), f(i+1,j), f(i,j+1))+1
  • 上面的迭代公式需要从4个方向向 i,j 计算
  • 实际上可以简化位2个方向
class Solution:
    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:
        h,w=len(mat),len(mat[0])

        dp=[[10000]*w for i in range(h)]
        for i in range(h):
            for j in range(w):
                if mat[i][j]==0:
                    dp[i][j]=0

        for i in range(h):
            for j in range(w):
                if i-1>=0:
                    dp[i][j]=min(dp[i][j],dp[i-1][j]+1)
                if j-1>=0:
                    dp[i][j]=min(dp[i][j],dp[i][j-1]+1)

        for i in range(h-1,-1,-1):
            for j in range(w-1,-1,-1):
                if i+1<h:
                    dp[i][j]=min(dp[i][j],dp[i+1][j]+1)
                if j+1<w:
                    dp[i][j]=min(dp[i][j],dp[i][j+1]+1)
        return dp

1975. Maximum Matrix Sum

这题简单:

  • 负号可以任意沿行/列移动
  • 每行偶数个负数字可以抵消,列也是
  • 如果全部偶数个负数,返回和
  • 如有有奇数个负数,转化为有1个负数,找到绝对值最小的那个即可
class Solution:
    def maxMatrixSum(self, matrix: List[List[int]]) -> int:
        h,w=len(matrix),len(matrix[0])
        neg_is_odds=True
        for i in range(h):
            for j in range(w):
                if matrix[i][j]<0:
                    neg_is_odds=not neg_is_odds

        res=0
        for i in range(h):
            for j in range(w):
                res+=abs(matrix[i][j])

        if neg_is_odds:
            return res
        else:
            min_num=100001
            for i in range(h):
                for j in range(w):
                    if min_num>abs(matrix[i][j]):
                        min_num = abs(matrix[i][j])
            return res-2*min_num

面试题 01.07. Rotate Matrix LCCI

经典的旋转题,都会背了

class Solution:
    def rotate(self, matrix: List[List[int]]) -> None:
        res=list(zip(*matrix[::-1]))
        n=len(matrix)
        for i in range(n):
            for j in range(n):
                matrix[i][j]=res[i][j]

519. Random Flip Matrix

  • 维护一个 dict,每个已经被筛选到的,映射到还没有被筛选到的
  • 下次如果还选到它,就选择它映射到的
  • ranint(idx) 中的 idx--,以减少搜索区域
import random

class Solution:

    def __init__(self, m: int, n: int):
        self.m = m
        self.n = n
        self.idx = m * n
        self.map = {}

    def flip(self) -> List[int]:
        self.idx -= 1
        x = random.randint(0, self.idx)
        new = self.map.get(x, x)
        self.map[x] = self.map.get(self.idx, self.idx)
        return divmod(new,self.n)

    def reset(self) -> None:
        self.idx = self.m * self.n
        self.map.clear()

不过话说用随机性出题就很屑,卡bug就行

class Solution:
    def __init__(self, m: int, n: int):
        self.mn = m*n
        self.n = n
        self.idx = 0

    def flip(self) -> List[int]:
        self.idx+=1
        if self.idx>=self.mn:
            self.idx=0
        return divmod(self.idx,self.n)

    def reset(self) -> None:
        pass

566. Reshape the Matrix

class Solution:
    def matrixReshape(self, mat: List[List[int]], r: int, c: int) -> List[List[int]]:
        if r*c==len(mat)*len(mat[0]):
            return np.array(mat).reshape(r,c).tolist()
        return mat

正经做也简单


class Solution:
    def matrixReshape(self, mat, r: int, c: int):
        h, w = len(mat), len(mat[0])
        if h * w != r * c:
            return mat

        res = [[None] * c for i in range(r)]
        for idx in range(h * w):
            new_i, new_j = divmod(idx, c)
            old_i, old_j = divmod(idx, w)
            res[new_i][new_j] = mat[old_i][old_j]

        return res

1572. 矩阵对角线元素的和

简单,一步过

class Solution:
    def diagonalSum(self, mat: List[List[int]]) -> int:
        res=0
        n=len(mat)
        for i in range(n):
            res+=mat[i][i]
            if i!=n-i-1:
                res+=mat[i][n-i-1]

        return res

面试题 01.08. Zero Matrix LCCI

class Solution:
    def setZeroes(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        h,w=len(matrix),len(matrix[0])
        row_not_0=[all(row) for row in matrix]
        col_not_0=[all(col) for col in zip(*matrix)]
        for idx,val in enumerate(row_not_0):
            if not val:
                matrix[idx]=[0]*w

        for idx,val in enumerate(col_not_0):
            if not val:
                for i in range(h):
                    matrix[i][idx]=0

885. Spiral Matrix III

!!! 此题是旋转类的典型题

和1/2差别是:

  • 1从外环向内旋转,提取
  • 2也是从外环向内旋转,填入
  • 3从内向外旋转。似乎下面的方法在1/2里面也能用,但1/2的旋转矩阵法就不那么通用了
class Solution:
    def spiralMatrixIII(self, rows: int, cols: int, rStart: int, cStart: int) -> List[List[int]]:
        res=[]
        direction=[(0,1),(1,0),(0,-1),(-1,0)] # 顺时针
        left,right,upper,bottom=cStart-1,cStart+1,rStart-1,rStart+1 # 边界
        x,y,num,direct=rStart,cStart,0,0
        while num<rows*cols:
            if x>=0 and x<rows and y>=0 and y<cols:
                res.append([x,y])
                num+=1

            # 遇到边界
            if direct==0 and y==right:
                direct=1
                right+=1
            elif direct==1 and x==bottom:
                direct=2
                bottom+=1
            elif direct==2 and y==left:
                direct=3
                left-=1
            elif direct==3 and x==upper:
                direct=0
                upper-=1
            x+=direction[direct][0]
            y+=direction[direct][1]

        return res

74. Search a 2D Matrix

二分法基础题,做一遍熟悉一下公式

class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        h,w=len(matrix),len(matrix[0])
        left,right=0,h*w-1

        while left<right:
            mid =(left+right)//2
            i,j=divmod(mid,w)
            if matrix[i][j]<target:
                left=mid+1
            elif matrix[i][j]>target:
                right=mid-1
            elif matrix[i][j]==target:
                return True

        mid=left

        i,j=divmod(mid,w)
        # print(mid,i,j)
        return matrix[i][j]==target

240. Search a 2D Matrix II

这个题一开始想用二分法,做了很久之后发现二分法不成立。下面是抄的(感觉这思路耦合性很大)

从左下角开始

  • 数值小,则往右
  • 数值大,则往上
class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        if not matrix:
            return False
        if not matrix[0]:
            return False

        h,w=len(matrix),len(matrix[0])
        i,j=h-1,0
        while i>=0 and j<w:
            if matrix[i][j]>target:
                i-=1
            elif matrix[i][j]<target:
                j+=1
            else:
                return True
        return False

面试题 10.09. Sorted Matrix Search LCCI

与 240. Search a 2D Matrix II 一样的题

1329. Sort the Matrix Diagonally

非常直白,不知道还有没有更好的方法

class Solution:
    def diagonalSort(self, mat: List[List[int]]) -> List[List[int]]:
        h,w=len(mat),len(mat[0])
        res=[[None]*w for i in range(h)]
        for k in range(-(h-1),w):
            if k<=0:
                tmp_lst=list()
                i1,j1=-k,0

                while i1<h and j1<w:
                    tmp_lst.append(mat[i1][j1])
                    i1+=1
                    j1+=1

                tmp_lst.sort()
                i1,j1=-k,0
                l=0

                while i1<h and j1<w:
                    res[i1][j1]=tmp_lst[l]
                    l+=1
                    i1+=1
                    j1+=1

            if k>0:
                tmp_lst=list()
                i1,j1=0,k

                while i1<h and j1<w:
                    tmp_lst.append(mat[i1][j1])
                    i1+=1
                    j1+=1

                tmp_lst.sort()
                i1,j1=0,k
                l=0
                while i1<h and j1<w:
                    res[i1][j1]=tmp_lst[l]
                    l+=1
                    i1+=1
                    j1+=1
        return res

861. Score After Flipping Matrix

  • 先反转行,使得第一列全1
  • 然后对每列,反转使1多于0
  • 进一步的,有些步骤不需要真的反转矩阵。
class Solution:
    def matrixScore(self, grid: List[List[int]]) -> int:
        h,w=len(grid),len(grid[0])
        for i in range(h):
            if grid[i][0]==0:
                for j in range(w):
                    grid[i][j]=1-grid[i][j]

        res=sum(grid[i][0] for i in range(h))

        for col in range(1,w):
            num_of_one=sum(grid[i][col] for i in range(h))
            if num_of_one<=h//2:
                for i in range(h):
                    grid[i][col]=1-grid[i][col]

            res=res<<1
            res+=(sum(grid[i][col] for i in range(h)))

        return res

其实第二步,矩阵不用真的反转

class Solution:
    def matrixScore(self, grid: List[List[int]]) -> int:
        h,w=len(grid),len(grid[0])
        for i in range(h):
            if grid[i][0]==0:
                for j in range(w):
                    grid[i][j]=1-grid[i][j]

        res=h

        for col in range(1,w):
            num_of_one=sum(grid[i][col] for i in range(h))
            res=res<<1
            res+=(max(num_of_one,h-num_of_one))

        return res

1632. Rank Transform of a Matrix

并查集+拓扑排序,之后做

https://leetcode-cn.com/problems/rank-transform-of-a-matrix/submissions/

1380. Lucky Numbers in a Matrix

不想用暴力搜索,所以推导一下得到更好的解法。

  1. 可以证明,结果必然是唯一的
  2. 那么结果必然是行最小和列最大的交集
class Solution:
    def luckyNumbers (self, matrix: List[List[int]]) -> List[int]:
        min_row={min(row) for row in matrix}
        max_col={max(col) for col in zip(*matrix)}
        return list(min_row&max_col)

1091. Shortest Path in Binary Matrix

!!!BFS 类似level order 的做法一定要会背。另外要知道这种方法是从 queue 而来的

class Solution:
    def shortestPathBinaryMatrix(self, grid) -> int:
        if grid[0][0] != 0:
            return -1

        h, w = len(grid), len(grid[0])

        if grid[h - 1][w - 1] != 0:
            return -1

        for i in range(h):
            for j in range(w):
                if grid[i][j] == 1:
                    grid[i][j] = None

        queue = [(0, 0)]
        grid[0][0] = 1
        level = 1

        while queue:
            new_queue = []
            for idx_i, idx_j in queue:
                if idx_i == h - 1 and idx_j == w - 1:
                    return level

                for diff_i, diff_j in ((1, 1), (-1, -1), (1, -1), (-1, 1), (0, 1), (1, 0), (0, -1), (-1, 0)):
                    new_i, new_j = idx_i + diff_i, idx_j + diff_j
                    if 0 <= new_i < h and 0 <= new_j < w and grid[new_i][new_j] == 0:
                        grid[new_i][new_j] = level
                        new_queue.append((new_i, new_j))

            queue = new_queue
            level += 1
        return -1

改矩阵的方法感觉不太美观,可以用一个 visited 变量来记录是否已经访问到。不过那样内存消耗就多了一点

1030. Matrix Cells in Distance Order

  • 还是需要用set来存放 visited,而不是直接判断 res,否则容易超时
class Solution:
    def allCellsDistOrder(self, rows: int, cols: int, rCenter: int, cCenter: int):
        queue, res,visited = {(rCenter, cCenter)}, [(rCenter, cCenter)],{(rCenter, cCenter)}

        while queue:
            # print(queue)
            new_queue = set()
            for idx_i, idx_j in queue:
                for diff_i, diff_j in ((-1, 0), (1, 0), (0, 1), (0, -1)):
                    new_i, new_j = idx_i + diff_i, idx_j + diff_j
                    if 0 <= new_i < rows and 0 <= new_j < cols and (new_i, new_j) not in visited:
                        new_queue.add((new_i, new_j))
            queue = new_queue
            res.extend(queue)
            visited.update(queue)

        return res

方法2:直接全部计算,然后sort,速度更快(以为这样很慢的)

class Solution:
    def allCellsDistOrder(self, rows: int, cols: int, rCenter: int, cCenter: int):
        dist_dict = dict()
        for i in range(rows):
            for j in range(cols):
                dist_dict[(i, j)] = abs(i - rCenter) + abs(j - cCenter)

        return sorted(dist_dict, key=lambda x: dist_dict[x])

简化一下,也就两行,哈哈哈

class Solution:
    def allCellsDistOrder(self, rows: int, cols: int, rCenter: int, cCenter: int):
        dist_dict = {(i, j): abs(i - rCenter) + abs(j - cCenter) for i in range(rows) for j in range(cols)}
        return sorted(dist_dict, key=lambda x: dist_dict[x])

1253. Reconstruct a 2-Row Binary Matrix

BFS总是超时,所以用直白方法输出一个解


class Solution:
    def reconstructMatrix(self, upper: int, lower: int, colsum):

        if upper + lower != sum(colsum):
            return []

        num_2, num_1, num_0, len_res = colsum.count(2), colsum.count(1), colsum.count(0), len(colsum)

        if upper - num_2 < 0 or lower - num_2 < 0:
            return []

        upper_num_1 = upper - num_2
        lower_num_1 = lower - num_2

        if upper_num_1 < 0 or lower_num_1 < 0 or upper_num_1 + lower_num_1 + num_2 + num_0 != len_res:
            return []

        res = []

        for i in colsum:
            if i == 2:
                res.append([1, 1])
            elif i == 0:
                res.append([0, 0])
            elif i == 1:
                if upper_num_1 > 0:
                    res.append([1, 0])
                    upper_num_1 -= 1
                else:
                    res.append([0, 1])

        return list(zip(*res))

1582. Special Positions in a Binary Matrix

class Solution:
    def numSpecial(self, mat: List[List[int]]) -> int:
        h,w=len(mat),len(mat[0])
        col_is_good=[None]*w

        res=0
        for i,row in enumerate(mat):
            if sum(row)==1:
                j=row.index(1)

                if col_is_good is None:
                    continue

                if sum(mat[i_1][j] for i_1 in range(h))>1:
                    col_is_good[j]=False
                    continue

                res+=1
        return res

378. Kth Smallest Element in a Sorted Matrix

import heapq


class Solution:
    def kthSmallest(self, matrix, k: int) -> int:
        n = len(matrix)
        heap = matrix[0] + [matrix[i][0] for i in range(1, n)]
        heapq.heapify(heap)

        for i in range(1, n):

            k_smallest = heapq.nsmallest(k, heap)

            if len(k_smallest) == k and matrix[i][i] > k_smallest[-1]:
                return k_smallest[k - 1]

            for val in matrix[i][i:]:
                heapq.heappush(heap, val)
            for i1 in range(i + 1, n):
                heapq.heappush(heap, matrix[i1][i])

        k_smallest = heapq.nsmallest(k, heap)

        return k_smallest[k - 1]

1337. The K Weakest Rows in a Matrix

直接用 heapq

import heapq

class Solution:
    def kWeakestRows(self, mat: List[List[int]], k: int) -> List[int]:
        res = heapq.nsmallest(k, iterable=[(i, sum(mat[i])) for i in range(len(mat))], key=lambda x: x[1])
        return list(zip(*res))[0]

1252. Cells with Odd Values in a Matrix

以下情况:

  1. 初始为偶数:如果一行只有一个,那么这一个仍是偶数,其它都变成奇数。
  2. 如果一行有2个,这两个是奇数,其它仍然是偶数。
  3. 也就是说,如果一行有奇数个,有数的全是偶数,其它全是奇数。一行有偶数个,有数的是奇数,其它全是偶数。

(以上作废,是我想复杂了)直白的做就行了

class Solution:
    def oddCells(self, m: int, n: int, indices: List[List[int]]) -> int:
        res=[[0]*n for i in range(m)]
        for (idx_i,idx_j) in indices:
            for i in range(m):
                res[i][idx_j]=1-res[i][idx_j]
            for j in range(n):
                res[idx_i][j]=1-res[idx_i][j]

        return sum(sum(row) for row in res)

1351. Count Negative Numbers in a Sorted Matrix

class Solution:
    def countNegatives(self, grid: List[List[int]]) -> int:
        return sum(sum(i < 0 for i in row) for row in grid)

1594. Maximum Non Negative Product in a Matrix

  1. 求全局值,所以用bfs而不是dfs
  2. 有个边界条件是格子里面可以为0,因此如果按照无0做的结果是空,并且有0,那么有个保底解是0
  3. 结果要取模
  4. queue要用set
class Solution:
    def maxProductPath(self, grid) -> int:
        h, w = len(grid), len(grid[0])

        queue = {(0, 0)}
        val = {(0, 0): [grid[0][0]]}

        def get_max(point_val, next_point, next_point_val):
            tmp = [i * next_point for i in point_val] + next_point_val
            tmp_min, tmp_max = min(tmp), max(tmp)
            if tmp_min < 0:
                if tmp_max >= 0:
                    return [tmp_min, tmp_max]
                if tmp_max < 0:
                    return [tmp_min]
            return [tmp_max]

        while queue:
            new_queue = set()
            for point in queue:
                for diff in ((1, 0), (0, 1)):
                    next_point = point[0] + diff[0], point[1] + diff[1]
                    if 0 <= next_point[0] < h and 0 <= next_point[1] < w:
                        val[next_point] = get_max(val[point], grid[next_point[0]][next_point[1]],
                                                  val[next_point] if next_point in val else list())


                        new_queue.add(next_point)
            queue = new_queue

        max_last_val = max(val[(h - 1, w - 1)])

        if max_last_val >= 0:
            return max_last_val%(10**9+7)
        else:

            for i in range(h):
                for j in range(w):
                    if grid[i][j] == 0:
                        return 0

            return -1

1605. Find Valid Matrix Given Row and Column Sums

class Solution:
    def restoreMatrix(self, rowSum, colSum):

        def get_matrix(rowSum, colSum):
            h, w = len(rowSum), len(colSum)
            if h == 0:
                return []
            num = rowSum[0]
            row = [0] * w
            i = 0
            while num > 0:
                # 贪心填充一行
                if num <= colSum[i]:
                    row[i] = num
                    colSum[i] -= num
                    num = 0
                else:
                    row[i] = colSum[i]
                    num -= colSum[i]
                    colSum[i] = 0
                i += 1

            return [row] + get_matrix(rowSum[1:], colSum)

        return get_matrix(rowSum, colSum)

1886. Determine Whether Matrix Can Be Obtained By Rotation

旋转类的基本题了,一次成型

class Solution:
    def findRotation(self, mat, target) -> bool:
        def rotate(mat):
            return list(zip(*mat))[::-1]

        target = [tuple(row) for row in target]
        mat_new = mat
        for i in range(4):
            mat_new = rotate(mat_new)
            if mat_new == target:
                return True

        return False

1284. Minimum Number of Flips to Convert Binary Matrix to Zero Matrix

!!!好题,想到这些:

  1. 如果某个解存在,那么其顺序任意调换不会影响结果
  2. 某一个格子翻转两次等于不翻转。
  3. 因此每个格子翻转1次或0次一定能得到答案。计算1的数量就能得到结果
  4. DFS 可解了,但是有 2n2n 复杂度
  5. 想到剪枝:如果某个格子附近都已经遍历过,但这个格子没有归0,那么这个分支不可能为解,剔除即可
  6. 发现第二行开始,都被剪成1种可能性了,这样的话只需要回溯第一行,2w2w复杂度
class Solution:
    def minFlips(self, mat) -> int:
        h, w = len(mat), len(mat[0])
        n = h * w
        res = [None]

        def flip(i, j):
            for diff_i, diff_j in ((0, -1), (0, 0), (0, 1), (-1, 0), (1, 0)):
                new_i, new_j = i + diff_i, j + diff_j
                if 0 <= new_i < h and 0 <= new_j < w:
                    mat[new_i][new_j] ^= 1

        def dfs(cnt, flip_cnt):
            if res[0] is not None:
                return

            if cnt == n:
                if sum(sum(row) for row in mat) == 0:
                    res[0] = flip_cnt
                return

            idx_i, idx_j = divmod(cnt, w)
            if idx_i == 0:
                # 第一个可能路径:不反转
                dfs(cnt + 1, flip_cnt)

                if res[0] is not None:
                    return

                # 第二个可能路径:翻转。这里用回溯法
                flip(idx_i, idx_j)
                dfs(cnt + 1, flip_cnt + 1)
                flip(idx_i, idx_j)

            else:
                if mat[idx_i - 1][idx_j] == 0:
                    dfs(cnt + 1, flip_cnt)
                else:
                    flip(idx_i, idx_j)
                    dfs(cnt + 1, flip_cnt + 1)
                    flip(idx_i, idx_j)

        dfs(0, 0)
        return res[0] if res[0] is not None else -1

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

  • 为了剪枝,每次迭代只取前k个即可(我咋没想到)
import heapq


class Solution:
    def kthSmallest(self, mat, k: int) -> int:
        total_sums = [0]
        for row in mat:
            total_sums = [total_sum + val for total_sum in total_sums for val in row]
            total_sums = heapq.nsmallest(k, total_sums)

        res = heapq.nsmallest(k, total_sums)
        return res[-1]

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK