LeetCode Hot100 - 矩阵篇

前言

刷力扣hot100,记录一下每题的思路~

这次是矩阵相关的题目

(1)73. 矩阵置零

①两个boolean数组记录要置零的行列号,遍历数组置零对应的行列

java 复制代码
class Solution {
    public void setZeroes(int[][] matrix) {
        int m=matrix.length, n=matrix[0].length;
        // 记录要置零的行列号
        boolean[] row=new boolean[m], col=new boolean[n];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(matrix[i][j]==0){
                    row[i]=true;
                    col[j]=true;
                }
            }
        }
        // 将对应行列置零
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(row[i]||col[j])matrix[i][j]=0;
            }
        }
    }
}

第一行第一列记录对应行列是否要置零。

0\]\[0\]同时代表行列,不能直接置零,使用两个boolean单独记录。 先遍历矩阵修改对应第一行第一列,置零除第一行第一列(标志位用于后续判断)的元素,再根据boolean处理第一行第一列 ```java class Solution { public void setZeroes(int[][] matrix) { int m=matrix.length, n=matrix[0].length; // [0][0]同时代表行列,不能直接置零,单独处理 boolean row0=false, col0=false; for(int j=0;j=0;i--){ // 第一行标志位最后处理 for(int j=1;j spiralOrder(int[][] matrix) { List ans = new ArrayList<>(); int m=matrix.length, n=matrix[0].length; // 行列 int[][] dir={{0,1},{1,0},{0,-1},{-1,0}}; // 方向矩阵 int x=0, y=0, dirIdx=0; // 当前位置、方向下标 boolean[][] flag = new boolean[m][n]; // 是否已访问 for(int i=0;i=m || y1<0||y1>=n || flag[x1][y1]) dirIdx=(dirIdx+1)%4; // 更新位置 x+=dir[dirIdx][0]; y+=dir[dirIdx][1]; } return ans; } } ``` ②**按层**模拟。 lrtb记录每层的上下左右,四个for循环遍历每边,前两个for循环之后修改了t和r,**后两个** for循环要**重新判断**是否满足t\<=b和l\<=r,判断上下或者左右是否已走完 ```java class Solution { public List spiralOrder(int[][] matrix) { List ans = new ArrayList<>(); int m=matrix.length, n=matrix[0].length; // 行列 int l=0, r=n-1, t=0, b=m-1; // 上下左右范围 while(l<=r&&t<=b){ for(int j=l; j<=r; j++)ans.add(matrix[t][j]); // 左到右 t++; for(int i=t; i<=b; i++)ans.add(matrix[i][r]); // 上到下 r--; if(t<=b) // 判断是否上下走完了 for(int j=r; j>=l; j--)ans.add(matrix[b][j]); // 右到左 b--; if(l<=r) // 判断左右是否走完了 for(int i=b; i>=t; i--)ans.add(matrix[i][l]); // 下到上 l++; } return ans; } } ``` ③同上,在**每个** for循环后判断**边界**是否合法,不合法就break,便于理解 ```java class Solution { public List spiralOrder(int[][] matrix) { List ans = new ArrayList<>(); int m=matrix.length, n=matrix[0].length; // 行列 int l=0, r=n-1, t=0, b=m-1; // 上下左右范围 while(l<=r&&t<=b){ for(int j=l; j<=r; j++)ans.add(matrix[t][j]); // 左到右 if(++t>b) break; for(int i=t; i<=b; i++)ans.add(matrix[i][r]); // 上到下 if(--r=l; j--)ans.add(matrix[b][j]); // 右到左 if(--b=t; i--)ans.add(matrix[i][l]); // 下到上 if(++l>r) break; } return ans; } } ``` ## (3)[48. 旋转图像](https://leetcode.cn/problems/rotate-image/description/?envType=study-plan-v2&envId=top-100-liked "48. 旋转图像") ①暴力。每次旋转包含四个数,从左上角开始遍历四分之一的位置,**逆时针** 替换,计算**每个替换值的位置**,只需要记录一个变量 ```java class Solution { public void rotate(int[][] matrix) { int n = matrix.length; // 左上角 for(int i=0;ib||l>r)return false; // 区域不存在 if(t==b&&l==r)return matrix[t][l]==target; // 一个元素 // 对角线 int i=t,j=l; for(;i<=b&&j<=r;i++,j++) if(matrix[i][j]>=target)break; if(i<=b&&j<=r&&matrix[i][j]==target)return true; // 在对角线上 // 左下和右上 return check(matrix,i,b,l,j-1,target)||check(matrix,t,i-1,j,r,target); } } ``` ③**二分查找**,对每行进行二分查找 ④**右上角** ,为一行最大和一列最小。若**大于** target,该列都大于target,y--;若**小于** target,该行都小于target,x++。直到找到。(类似从**左下角**开始也可以,条件反过来) ```java class Solution { public boolean searchMatrix(int[][] matrix, int target) { int m=matrix.length, n=matrix[0].length; int x=0,y=n-1; // 右上角开始 while(x=0){ if(matrix[x][y]==target)return true; // 找到 if(matrix[x][y]>target)y--; // y这列都大于target else x++; // x这行都小于target } return false; } } ``` ## 总结 ①**矩阵置零** 。使用**第一行第一列**来标记每行每列,注意特别判断\[0\]\[0\]位置 ②**螺旋矩阵** 。用**方向数组和下标** 模拟旋转;**按层**遍历,用lrtp记录上下左右要遍历的层,要注意判断边界是否合法 ③**旋转矩阵** 。总结**旋转规律** ,i,j旋转到j,n-i-1,逆时针替换只需要记录一个变量;先**转置** 为j,i,再**左右翻转**为j,n-i-1 ④**搜索二维矩阵Ⅱ** 。**暴力** 遍历;**递归** ,从对角线开始判断,划分四个区域,递归左下和右上;对每行用**二分查找** ;利用**右上** 或者**左下**的特殊性,每次收缩一行或一列。

相关推荐
OpenC++23 分钟前
【C++QT】Buttons 按钮控件详解
c++·经验分享·qt·leetcode·microsoft
知来者逆2 小时前
计算机视觉——速度与精度的完美结合的实时目标检测算法RF-DETR详解
图像处理·人工智能·深度学习·算法·目标检测·计算机视觉·rf-detr
阿让啊2 小时前
C语言中操作字节的某一位
c语言·开发语言·数据结构·单片机·算法
এ᭄画画的北北2 小时前
力扣-160.相交链表
算法·leetcode·链表
爱研究的小陈3 小时前
Day 3:数学基础回顾——线性代数与概率论在AI中的核心作用
算法
渭雨轻尘_学习计算机ing3 小时前
二叉树的最大宽度计算
算法·面试
BB_CC_DD3 小时前
四. 以Annoy算法建树的方式聚类清洗图像数据集,一次建树,无限次聚类搜索,提升聚类搜索效率。(附完整代码)
深度学习·算法·聚类
梁下轻语的秋缘5 小时前
每日c/c++题 备战蓝桥杯 ([洛谷 P1226] 快速幂求模题解)
c++·算法·蓝桥杯
CODE_RabbitV5 小时前
【深度强化学习 DRL 快速实践】逆向强化学习算法 (IRL)
算法
mit6.8245 小时前
[贪心_7] 最优除法 | 跳跃游戏 II | 加油站
数据结构·算法·leetcode