• 【Leetcode】top 100 矩阵


    73 矩阵置零

    给定一个 m x n 的矩阵,如果一个元素为 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法

    方法一:拷贝出一个同样大小的矩阵,根据拷贝矩阵在原矩阵上修改元素;   空间复杂度O(mn)

    方法二:第一次遍历用row记录第几行需要被改变,用column记录第几列需要被改变;第二次遍历再修改,若当前行需要被改变,直接全置零,若当前行不需要被改变,再改变当前行中被列上的0影响的元素;    空间复杂度O(m+n),时间复杂度O(2mn)

    因为第二次遍历时需要查找值,用了集合;

    1. class Solution(object):
    2. def setZeroes(self, matrix):
    3. """
    4. :type matrix: List[List[int]]
    5. :rtype: None Do not return anything, modify matrix in-place instead.
    6. """
    7. row, column = set(), set()
    8. m, n = len(matrix), len(matrix[0])
    9. for i in range(m):
    10. for j in range(n):
    11. if matrix[i][j] == 0:
    12. row.add(i)
    13. column.add(j)
    14. for i in range(m):
    15. if i in row:matrix[i] = [0] * n
    16. else:
    17. for j in column:
    18. matrix[i][j] = 0
    19. return matrix

    官方思路:用第一行记录行改变情况(第一行为row),用第一列记录列改变情况(第一列为column)损失的第一行和第一列信息用变量储存;只需要记录第一行第一列是否有0即可,若有0,更新后的状态需要全0,即损失的初始状态不重要;若无0,更新后的状态只会受到该行或该列的影响,所以提前置零记录该行或该列情况不影响最终结果;     空间复杂度O(1)

    1. class Solution(object):
    2. def setZeroes(self, matrix):
    3. """
    4. :type matrix: List[List[int]]
    5. :rtype: None Do not return anything, modify matrix in-place instead.
    6. """
    7. row, column = 1, 1
    8. m, n = len(matrix), len(matrix[0])
    9. for i in range(n): #第一行情况
    10. if matrix[0][i] == 0: row = 0
    11. for i in range(m): #第一列情况
    12. if matrix[i][0] == 0: column = 0
    13. for i in range(1,m): #记录需要改变的行和列
    14. for j in range(1,n):
    15. if matrix[i][j] == 0:
    16. matrix[0][j] = 0
    17. matrix[i][0] = 0
    18. for i in range(1,m): #根据记录修改行和列
    19. for j in range(1,n):
    20. if matrix[0][j] == 0 or matrix[i][0] == 0:
    21. matrix[i][j] = 0
    22. if row == 0: #更新第一行
    23. for i in range(n):
    24. matrix[0][i] = 0
    25. if column == 0: #更新第一列
    26. for i in range(m):
    27. matrix[i][0] = 0
    28. return matrix
    54 螺旋矩阵

    给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

    分析:一定会转满min(m//2, n//2)圈,最后不剩/剩一行/剩一列/剩一个中心元素;

    思路一:直接模拟

    1. class Solution(object):
    2. def spiralOrder(self, matrix):
    3. """
    4. :type matrix: List[List[int]]
    5. :rtype: List[int]
    6. """
    7. out = []
    8. n, m = len(matrix), len(matrix[0])
    9. up, left, down, right = 0, 0, n-1, m-1
    10. for i in range(min(m,n)//2):
    11. for j in range(left,right+1):
    12. out.append(matrix[up][j])
    13. up += 1
    14. for j in range(up,down+1):
    15. out.append(matrix[j][right])
    16. right -= 1
    17. for j in range(right,left-1,-1):
    18. out.append(matrix[down][j])
    19. down -= 1
    20. for j in range(down,up-1,-1):
    21. out.append(matrix[j][left])
    22. left += 1
    23. if min(m,n) % 2 != 0:
    24. if n > m:
    25. for j in range(up,down+1):
    26. out.append(matrix[j][right])
    27. elif n < m:
    28. for j in range(left,right+1):
    29. out.append(matrix[up][j])
    30. else:
    31. out.append(matrix[n//2][m//2])
    32. return out

    思路二:循环用while true,直至指针交错(相等是允许的)才退出;

    1. class Solution(object):
    2. def spiralOrder(self, matrix):
    3. """
    4. :type matrix: List[List[int]]
    5. :rtype: List[int]
    6. """
    7. res = []
    8. if matrix is None: return res
    9. top,bottom,left,right = 0, len(matrix) - 1, 0, len(matrix[0]) - 1
    10. while True:
    11. for i in range(left,right+1): #➡️
    12. res.append(matrix[top][i])
    13. top += 1
    14. if top > bottom: break
    15. for i in range(top,bottom+1): #⬇️
    16. res.append(matrix[i][right])
    17. right -= 1
    18. if right < left: break
    19. for i in range(right,left-1,-1): #⬅️
    20. res.append(matrix[bottom][i])
    21. bottom -= 1
    22. if bottom < top: break
    23. for i in range(bottom,top-1,-1): #⬆️
    24. res.append(matrix[i][left])
    25. left += 1
    26. if left > right: break
    27. return res

    思路三利用zip和*的搭配实现行列的转换; 原第一行取完后,将列转行再倒序,就能取到原最后一列;由于倒序操作改变了原行内的相对位置,恰好满足原最后一行的倒序输出;

    这是真牛!!!

    1. class Solution(object):
    2. def spiralOrder(self, matrix):
    3. """
    4. :type matrix: List[List[int]]
    5. :rtype: List[int]
    6. """
    7. out = []
    8. while matrix:
    9. out += matrix.pop(0)
    10. matrix = list(zip(*matrix))[::-1]
    11. return out
    48 旋转图像

    给定一个 × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

    分析:观察旋转图像发现,其实就是转置再翻转

    转置:list(zip(*))     [( )( )( )]     

               list(map(list, zip(*matrix))) == list(row) for row in zip(*matrix)     [[ ][ ][ ]]

    翻转:[::-1]

    1. class Solution(object):
    2. def rotate(self, matrix):
    3. """
    4. :type matrix: List[List[int]]
    5. :rtype: None Do not return anything, modify matrix in-place instead.
    6. """
    7. matrix[:] = [row[::-1] for row in zip(*matrix)]
    240 搜索二维矩阵II

    编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:每行的元素从左到右升序排列;每列的元素从上到下升序排列。

    分析:利用 matrix 特性减少搜索时间:

    小于当前行起始值,就不可能再在后续中找到;

    大于当前行终止值,该行不遍历;

    在当前行的范围内,小于当前列值,后续就只能在较小的列中寻找;大于当前列值,继续遍历;

    1. class Solution(object):
    2. def searchMatrix(self, matrix, target):
    3. """
    4. :type matrix: List[List[int]]
    5. :type target: int
    6. :rtype: bool
    7. """
    8. if target < matrix[0][0] or target > matrix[-1][-1]:
    9. return False
    10. m, n = len(matrix), len(matrix[0])
    11. for i in range(m):
    12. if target < matrix[i][0]:return False
    13. elif target > matrix[i][-1]:continue
    14. else:
    15. for j in range(n):
    16. if target < matrix[i][j]:n = j
    17. elif target == matrix[i][j]:return True
    18. else:continue
    19. return False

    官方思路:从矩阵的右上角开始Z字遍历

    当目标值大于这个值,目标值就不能在当前行被找到;

    当目标值小于这个值,目标值就不能在当前列被找到;

    1. class Solution:
    2. def searchMatrix(self, matrix, target):
    3. m, n = len(matrix), len(matrix[0])
    4. i, j = m - 1, 0
    5. while i >= 0 and j < n:
    6. if matrix[i][j] == target:return True
    7. elif matrix[i][j] < target:j += 1
    8. else:i -= 1
    9. return False
  • 相关阅读:
    linux 安装中文字体
    会议AISTATS(Artificial Intelligence and Statistics) Latex模板参考文献引用问题
    [Java SE] 经典问题:超出Java Long型(8字节/64位)的二进制比特流数据如何进行大数的数值计算?
    sprintboot项目通过interceptor和filter实现接入授权控制
    Ubuntu22.04安装Go语言的几种方式
    SpringBoot--maven-wrapper(mvnw)--使用/详解
    [附源码]计算机毕业设计JAVA家乡旅游文化推广系统
    UIC Python期末冲刺|02文件操作1
    Unity | Shader(着色器)和material(材质)的关系
    git基本使用手册
  • 原文地址:https://blog.csdn.net/qq_45430996/article/details/136619312