ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

hot100矩阵问题

hot100矩阵问题

73. 矩阵置零 - 力扣(LeetCode)

一边标记一边改值有读写问题、

用两个布尔标记第一行和第一列的是否存在0

用第一行和第一列作为剩余位置的是否存在0的标记

class Solution { public void setZeroes(int[][] matrix) { int m = matrix.length; int n = matrix[0].length; boolean row=false; boolean col=false; for(int i=0;i<n;i++){ if(matrix[0][i]==0){ row=true; break; } } for(int i=0;i<m;i++){ if(matrix[i][0]==0){ col=true; break; } } for(int i=1;i<m;i++){ for(int j=1;j<n;j++){ if(matrix[i][j]==0){ matrix[0][j]=0; matrix[i][0]=0; } } } for(int i=1;i<m;i++){ for(int j=1;j<n;j++){ if(matrix[0][j]==0 || matrix[i][0]==0){ matrix[i][j]=0; } } } if(row){ for(int i=0;i<n;i++){ matrix[0][i]=0; } } if(col){ for(int i=0;i<m;i++){ matrix[i][0]=0; } } } }

54. 螺旋矩阵 - 力扣(LeetCode)

这个写错了,不应该按照正方形的思路去做,存在一种通用矩形方法

定义四个角落的位置,然后每次走完一个边界就修改边界,注意后两次循环要加上判断条件,因为前两次循环可能超边界了。

  • 上边取的是当前圈的top行,这一行在当前圈里还没被取过。

  • 右边取的是当前圈的right列,这一列在当前圈里还没被取过。

  • 下边取的是bottom行,但单行时bottom == top,这一行已经被上边取过了。

  • 左边取的是left列,但单列时left == right,这一列已经被右边取过了。

class Solution { public List<Integer> spiralOrder(int[][] matrix) { int m=matrix.length; int n=matrix[0].length; ArrayList<Integer> res=new ArrayList<>(); int top=0, bottom=m-1, left=0, right=n-1; while(top<=bottom && left<=right){ for(int i=left;i<=right;i++){ res.add(matrix[top][i]); } top++; for(int i=top;i<=bottom;i++){ res.add(matrix[i][right]); } right--; if(top<=bottom){ for(int i=right;i>=left;i--){ res.add(matrix[bottom][i]); } bottom--; } if(left<=right){ for(int i=bottom;i>=top;i--){ res.add(matrix[i][left]); } left++; } } return res; } }

240. 搜索二维矩阵 II - 力扣(LeetCode)

因为一个方向是最大值,另一个方向是最小值。这样才能在每一步比较后,确定唯一该往哪走,从而排除一整行或一整列。

class Solution { public boolean searchMatrix(int[][] matrix, int target) { int m = matrix.length; int n = matrix[0].length; int startrow=0; int startcol=n-1; while(startrow<m && startcol>=0){ if(matrix[startrow][startcol]==target){ return true; }else if(matrix[startrow][startcol]>target){ startcol--; }else{ startrow++; } } return false; } }

48. 旋转图像 - 力扣(LeetCode)

常见的简单操作有:

  • 转置:(i, j) → (j, i)

  • 左右翻转:(i, j) → (i, n - 1 - j)

  • 上下翻转:(i, j) → (n - 1 - i, j)

根据这三种操作改变,本题是先转置下三角,然后翻转一半的列

class Solution { public void rotate(int[][] matrix) { // 147 // 258 // 369 int m=matrix.length; int n=matrix[0].length; for(int i=0;i<m;i++){ for(int j=0;j<=i;j++){ int temp = matrix[i][j]; matrix[i][j]=matrix[j][i]; matrix[j][i]=temp; } } for(int i=0;i<m;i++){ for(int j=0;j<n/2;j++){ int temp = matrix[i][j]; matrix[i][j]=matrix[i][n-j-1]; matrix[i][n-j-1]=temp; } } } }
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进