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 ④**搜索二维矩阵Ⅱ** 。**暴力** 遍历;**递归** ,从对角线开始判断,划分四个区域,递归左下和右上;对每行用**二分查找** ;利用**右上** 或者**左下**的特殊性,每次收缩一行或一列。

相关推荐
想跑步的小弱鸡2 小时前
Leetcode hot 100(day 3)
算法·leetcode·职场和发展
xyliiiiiL3 小时前
ZGC初步了解
java·jvm·算法
爱的叹息4 小时前
RedisTemplate 的 6 个可配置序列化器属性对比
算法·哈希算法
独好紫罗兰4 小时前
洛谷题单2-P5713 【深基3.例5】洛谷团队系统-python-流程图重构
开发语言·python·算法
每次的天空5 小时前
Android学习总结之算法篇四(字符串)
android·学习·算法
请来次降维打击!!!5 小时前
优选算法系列(5.位运算)
java·前端·c++·算法
qystca5 小时前
蓝桥云客 刷题统计
算法·模拟
别NULL6 小时前
机试题——统计最少媒体包发送源个数
c++·算法·媒体
weisian1516 小时前
Java常用工具算法-3--加密算法2--非对称加密算法(RSA常用,ECC,DSA)
java·开发语言·算法
程序员黄同学7 小时前
贪心算法,其优缺点是什么?
算法·贪心算法