解法一:(使用两个标记变量)用矩阵的第一行和第一列代替方法一中的两个标记数组(col、row[ ]:第几列、行出现0),以达到 O(1) 的额外空间。
- 这样会导致原数组的第一行和第一列被修改,无法记录它们是否原本包含 0。因此我们需要额外使用两个标记变量分别记录第一行和第一列是否原本包含 0。
- 在实际代码中,我们首先预处理出两个标记变量,接着使用其他行与列去处理第一行与第一列,然后反过来使用第一行与第一列去更新其他行与列,最后使用两个标记变量更新第一行与第一列即可。
java
class Solution {
public void setZeroes(int[][] matrix) {
int m=matrix.length, n=matrix[0].length;
boolean row=false, col=false;
// 判断第一行有没有0
for(int i=0; i<n; i++){
if(matrix[0][i]==0){
row=true;
}
}
// 判断第一列有没有0
for(int i=0; i<m; i++){
if(matrix[i][0]==0){
col=true;
}
}
// 判断数组中是否有0 -> ij都是从1开始
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;
}
}
}
// 第一行出现0的列+第一列出现0的行=0 -> ij都是从1开始
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
if(matrix[i][0]==0 || matrix[0][j]==0){
// 只要matrix[i][0]==0或者matrix[0][j]==0,则matrix[i][j]==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;
}
}
}
}
注意:
- 同时涉及到ij时,ij都是从1开始 -> 只处理除了第一行和第一列的数