leetcode_day14_矩阵_《绝境求生》

目录


​前言

碎碎念:某节,某鹅,某里,某团,某东,某度,某手。被自己的前途亮得睡不着

talk is cheap, show me your work


还有高手

一、矩阵置零

1、题目描述

给定一个 m x n 的矩阵,若某个元素为 0,则将其所在行和列的所有元素置为 0,必须使用原地算法(空间复杂度优化至 O (1))

示例 1:

复制代码
输入:matrix = [[1,1,1],[1,0,1],[1,1,1]]
输出:[[1,0,1],[0,0,0],[1,0,1]]

示例 2:

复制代码
输入:matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
输出:[[0,0,0,0],[0,4,5,0],[0,3,1,0]]

2、简单理解?

利用矩阵自身的第一行和第一列作为「标记空间」,避免额外数组开销:

  1. 先记录第一行、第一列是否原本包含 0(后续标记会覆盖原始值,需提前保存);
  2. 遍历矩阵(从第二行第二列开始),若元素为 0,则将其所在行的第一个元素、所在列的第一个元素置为 0(标记该行 / 列需置零);
  3. 根据第一行 / 列的标记,将对应行、列置零;
  4. 最后根据初始记录,决定是否将第一行 / 列整体置零。

非常机械,无需思考根据步骤来就行

检查第一行是否有0,检查第一列是否有0

,从(1,1)开始遍历是否有0,有就置0那一行列第一个数,

根据第一列标记 置零对应整行

根据第一行标记置零对应整列

根据标志位处理第一行第一列

3、用图示意

4、暴力法

5、优化法

python 复制代码
def setZeroes(matrix):
    if not matrix or not matrix[0]:
        return
    m, n = len(matrix), len(matrix[0])
    row0 = any(matrix[0][j] == 0 for j in range(n))  # 首行是否有0
    col0 = any(matrix[i][0] == 0 for i in range(m))  # 首列是否有0

    # 标记需置零的行/列
    for i in range(1, m):
        for j in range(1, n):
            if matrix[i][j] == 0:
                matrix[i][0] = matrix[0][j] = 0

    # 按标记置零(行)
    for i in range(1, m):
        if matrix[i][0] == 0:
            matrix[i] = [0] * n

    # 按标记置零(列)
    for j in range(1, n):
        if matrix[0][j] == 0:
            for i in range(m):
                matrix[i][j] = 0

    # 处理首行/首列
    if row0: matrix[0] = [0] * n
    if col0:
        for i in range(m):
            matrix[i][0] = 0

if __name__ == "__main__":
    import sys
    input = sys.stdin.read().split()
    ptr = 0
    m = int(input[ptr]); ptr +=1
    n = int(input[ptr]); ptr +=1
    mat = []
    for _ in range(m):
        row = list(map(int, input[ptr:ptr+n]))
        ptr +=n
        mat.append(row)
    setZeroes(mat)
    for row in mat:
        print(' '.join(map(str, row)))

6、疑惑点/新知识 ? 之前见过但没注意到的?

怎么得到矩阵的row和col

规矩:矩阵中 列遍历用j,行遍历用i

二、螺旋矩阵

1、题目描述

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

示例 1:

复制代码
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]

示例 2:

复制代码
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 10
  • -100 <= matrix[i][j] <= 100

2、简单理解?

一个matrix,顺时针,从上到下,从左到右遍历元素并收缩边界。

界定为边界问题,

3、能不能用图示意?

4、暴力法

5、优化法

python 复制代码
def main():
    import sys
    input = sys.stdin.read().split()
    ptr = 0
    m = int(input[ptr])
    ptr +=1
    n = int(input[ptr])
    ptr +=1
    matrix = []
    for _ in range(m):
        row = list(map(int, input[ptr:ptr+n]))
        matrix.append(row)
        ptr +=n
    
    # 核心逻辑
    res = []
    if not matrix or not matrix[0]:
        print(res)
        return
    
    top, bottom = 0, m-1
    left, right = 0, n-1
    
    while top <= bottom and left <= right:
        # 1. 从左到右遍历上边界
        for j in range(left, right+1):
            res.append(matrix[top][j])
        top +=1
        
        # 2. 从上到下遍历右边界
        for i in range(top, bottom+1):
            res.append(matrix[i][right])
        right -=1
        
        # 3. 从右到左遍历下边界(需判断top<=bottom)
        if top <= bottom:
            for j in range(right, left-1, -1):
                res.append(matrix[bottom][j])
            bottom -=1
        
        # 4. 从下到上遍历左边界(需判断left<=right)
        if left <= right:
            for i in range(bottom, top-1, -1):
                res.append(matrix[i][left])
            left +=1
    
    # 输出结果(ACM格式)
    print(' '.join(map(str, res)))

if __name__ == "__main__":
    main()

6、疑惑点/新知识 ?之前见过但没注意到的?

在母串中枚举所有长度是len_子串,范围是 len_母串-len_子串+1

写错了 s[ i : i+len(p)] 是冒号不是逗号

三、旋转图像

1、题目描述

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

你必须在**原地** 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。

示例 1:

复制代码
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[[7,4,1],[8,5,2],[9,6,3]]

示例 2:

复制代码
输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]
输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]

提示:

  • n == matrix.length == matrix[i].length
  • 1 <= n <= 20
  • -1000 <= matrix[i][j] <= 1000

2、简单理解?

一个matrix,顺时针原地旋转90度,

实现方法,先转置矩阵,然后再反转每一行,最后效果跟顺时针转90度一样

3、能不能用图示意?

4、暴力法

5、优化法

python 复制代码
class Solution:
    def rotate(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        row=len(matrix)
        col=len(matrix[0])
        if not matrix or col==1:
            return matrix  #无需反转,返回原来的矩阵
        
        #实现转置
        for j in range(col):
            for i in range(j+1,row):
                matrix[j][i],matrix[i][j]=matrix[i][j],matrix[j][i]
        
        #反转每一行 
        for i in range(row):
            matrix[i]=matrix[i][::-1]
        return matrix

6、疑惑点/新知识 ?之前见过但没注意到的?

四、搜索二维矩阵

1、题目描述

编写一个高效的算法来搜索 m xn 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:

  • 每行的元素从左到右升序排列。
  • 每列的元素从上到下升序排列。

示例 1:

复制代码
输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5
输出:true

示例 2:

复制代码
输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 20
输出:false

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= n, m <= 300
  • -109 <= matrix[i][j] <= 109
  • 每行的所有元素从左到右升序排列
  • 每列的所有元素从上到下升序排列
  • -109 <= target <= 109

2、简单理解?

判断目标值target是否在矩阵中?

简单说就是先看列的单调性,直到列比target小 开始单调行

优化思路(时间复杂度 O (m+n),无需额外空间):从矩阵右上角开始遍历(也可从左下角),利用单调性缩小范围:

  1. 初始化行指针i=0,列指针j=n-1(右上角);
  2. 循环判断:
    • matrix[i][j] == target:找到目标,返回 True;
    • matrix[i][j] > target:目标更小,向左移动列指针(j-=1);
    • matrix[i][j] < target:目标更大,向下移动行指针(i+=1);
  3. 若指针越界(i>=m 或 j<0),返回 False。

3、能不能用图示意?

4、暴力法

5、优化法

python 复制代码
class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        row,col=len(matrix),len(matrix[0])
          

        #边界条件:矩阵为空,目标大于矩阵最大或者小于矩阵最小
  
        if not matrix or not matrix[0]:
            return False
        found=False
        i,j=0,col-1
        while i<row and j>=0:
            if matrix[i][j]==target:
                found= True
                # return True
                break
            elif matrix[i][j]>target:
                j-=1
            elif matrix[i][j]<target:
                i+=1
            
        
        return True if found else False
        # return False


        

6、疑惑点/新知识 ?之前见过但没注意到的?


相关推荐
很搞笑的在打麻将2 小时前
Java集合线程安全实践:从ArrayList数据迁移问题到synchronizedList解决方案
java·jvm·算法
小小仙。2 小时前
IT自学第十八天
java·开发语言·算法
LDG_AGI2 小时前
【机器学习】深度学习推荐系统(二十八):X 推荐算法listwiseRescoring(同刷多样性降权)机制详解
人工智能·分布式·深度学习·算法·机器学习·推荐算法
Yupureki2 小时前
《算法竞赛从入门到国奖》算法基础:入门篇-贪心算法(上)
c语言·数据结构·c++·算法·贪心算法·visual studio
散峰而望2 小时前
【算法竞赛】队列和 queue
开发语言·数据结构·c++·算法·链表·github·线性回归
丶小鱼丶2 小时前
Java基础之【排序算法】
java·算法
乐迪信息2 小时前
乐迪信息:AI视频分析技术用于船舶倾斜监控
大数据·网络·人工智能·算法·无人机
知乎的哥廷根数学学派2 小时前
基于物理约束指数退化与Hertz接触理论的滚动轴承智能退化趋势分析(Pytorch)
开发语言·人工智能·pytorch·python·深度学习·算法·机器学习