力扣73.矩阵置零、54.螺旋矩阵、48.旋转图像

73.矩阵置零

一、空间复杂度O(m + n)

思路:

根据题目给的示例比较容易想到循环遍历一次记录下为0元素的行和列,再循环遍历两次分别把为0元素对应的行及列上的元素置为0。

代码:

python 复制代码
class Solution:
    def setZeroes(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        m = len(matrix)
        n = len(matrix[0])
        idx_i = []
        idx_j = []

        for i in range(m):
            for j in range(n):
                if matrix[i][j] == 0:
                    idx_i.append(i)
                    idx_j.append(j)

        for i in range(len(idx_i)):
            for j in range(n):
                matrix[idx_i[i]][j] = 0

        for i in range(m):
            for j in range(len(idx_j)):
                matrix[i][idx_j[j]] = 0
                

二、空间复杂度O(1)

思路:

从第一种方法利用两个列表来记录改进为使用两个变量来记录。首先,可以使用本身矩阵的第一行和第一列来记录该行该列是否有为0元素,直接原地操作,不新建列表记录;其次,这种记录方式没有考虑本身首行和首列是否存在含0的情况,故增加两个单独变量来记录首行和首列是否存在含0元素,最后单独处理这种情况。

代码:

python 复制代码
class Solution:
    def setZeroes(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        m = len(matrix)
        n = len(matrix[0])
        
        first_row_has_zero = 0 in matrix[0]  # 记录第一行是否包含 0
        first_col_has_zero = any(row[0] == 0 for row in matrix)  # 记录第一列是否包含 0

        # 用第一列 matrix[i][0]保存本列是否有0值
        # 用第一行 matrix[0][j]保存本行是否有0值
        # 都不遍历首行或首列,因为有先定义的两个变量看了首行首列是否有0
        for i in range(1, m):
            for j in range(1, n):
                if matrix[i][j] == 0:
                    matrix[i][0] = 0
                    matrix[0][j] = 0

        for i in range(1, m):
            for j in range(1, n):
                if matrix[i][0] == 0 or matrix[0][j] == 0:
                    matrix[i][j] = 0

        # 如果第一行一开始就包含 0,那么把第一行全变成 0
        if first_row_has_zero:
            for j in range(n):
                matrix[0][j] = 0

         # 如果第一列一开始就包含 0,那么把第一列全变成 0
        if first_col_has_zero:
            for row in matrix:
                row[0] = 0
                

参考:力扣灵神题解

记录一下不太熟悉的语法:

  • *matrix 将矩阵的每一行解包为独立的参数传递给 zip。
  • zip 函数会将这些行的对应位置的元素组合成元组,形成新的列。

54.螺旋矩阵

思路:

分别设置四个边界up,down,left,right用于指代上下左右,按顺时针螺旋顺序用四个循环来遍历这四个边界;新建列表和计数下标,用于记录四个循环遍历到的数来存进去。

注意:

up、down确定行,left、right确定列,下标不要搞混了

代码:

python 复制代码
class Solution:
    def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
        m, n = len(matrix), len(matrix[0])
        up, down, left, right = 0, m - 1, 0, n - 1
        count = 0
        nums = [0] * m * n

        while(True):
            for j in range(left, right + 1):
                nums[count] = matrix[up][j]
                count += 1
            up += 1
            if up > down:
                break

            for i in range(up, down + 1):
                nums[count] = matrix[i][right]
                count += 1
            right -= 1
            if right < left:
                break

            for j in range(right, left - 1, -1):
                nums[count] = matrix[down][j]
                count += 1
            down -= 1
            if down < up:
                break

            for i in range(down, up - 1, -1):
                nums[count] = matrix[i][left]
                count += 1
            left += 1
            if left > right:
                break

        return nums

参考:代码随想录

48.旋转图像

整体思路:

整体的思路方法都是先把矩阵转置然后以列对称轴为中心两边元素交换。如果下次回忆不起来就自己用示例画一下

注意:

1、矩阵转置时只要对上三角或下三角进行转置,也就是说,j要么范围为(i + 1, n - 1),要么范围为(0, i - 1),要不然就相当于两次转置转回来了

2、区分偶数列和奇数列进行交换,一开始第一种写法没有加判断条件怎么写也不对,发现偶数会多换一次...真鸡肋啊这笨脑子,而且忘记了可以直接用内置函数交换...

一、两个循环写法

python 复制代码
class Solution:
    def rotate(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        m, n = len(matrix), len(matrix[0])

        # 矩阵转置
        for i in range(m):
            for j in range(i + 1, n):
                matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]

        for i in range(m):
            for j in range(n // 2 + 1):
                if j == n // 2:
                    continue
                matrix[i][j], matrix[i][n - j - 1] = matrix[i][n - j - 1],matrix[i][j]

或者:

python 复制代码
class Solution:
    def rotate(self, matrix: List[List[int]]) -> None:
        n = len(matrix)
        # 第一步:转置
        for i in range(n):
            for j in range(i):  # 遍历对角线下方元素
                matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]

        # 第二步:行翻转
        for row in matrix:
            row.reverse()

参考:灵神

二、一个循环

思路:

之前的两种写法都是分为两个循环,分别进行转置和列交换,一个循环的方法就是把转置和列交换放在一个循环里面,在一行进行完转置的操作之后,就已经可以在这一行以列为中轴进行交换了

代码:

python 复制代码
class Solution:
    def rotate(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        m= len(matrix)

        for i, row in enumerate(matrix):
            for j in range(i + 1, m):
                # row[j]相当于matrix[i][j]
                row[j], matrix[j][i] = matrix[j][i], row[j]
            # 在一行进行完转置的操作之后,就已经可以在这一行以列为中轴进行交换了
            row.reverse()

参考:灵神

相关推荐
DuHz2 小时前
矩阵束法(Matrix Pencil)用于 FMCW 雷达干扰抑制:论文精读
人工智能·机器学习·矩阵
BHXDML2 小时前
第一章:线性回归& 逻辑回归
算法·逻辑回归·线性回归
iAkuya2 小时前
(leetcode)力扣100 二叉搜索树种第K小的元素(中序遍历||记录子树的节点数)
算法·leetcode·职场和发展
weixin_462446232 小时前
Python 使用 openpyxl 从 URL 读取 Excel 并获取 Sheet 及单元格样式信息
python·excel·openpyxl
毕设源码-钟学长3 小时前
【开题答辩全过程】以 基于Python的健康食谱规划系统的设计与实现为例,包含答辩的问题和答案
开发语言·python
Remember_9933 小时前
【LeetCode精选算法】滑动窗口专题二
java·开发语言·数据结构·算法·leetcode
百***78753 小时前
Grok-4.1技术深度解析:双版本架构突破与Python API快速集成指南
大数据·python·架构
Gorgous—l4 小时前
数据结构算法学习:LeetCode热题100-动态规划篇(下)(单词拆分、最长递增子序列、乘积最大子数组、分割等和子集、最长有效括号)
数据结构·学习·算法
2501_942191774 小时前
基于YOLO11-HSFPN的数字检测与识别模型实现详解
python