题目描述
给定一个矩阵,如果有零元素那么就将零元素所在的行和列都置为零。Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place.
题目的难点就在于,如果遇到零元素之后马上在矩阵上操作,将所在的行和列都置为零。在接下来的遍历中,如果你再遇到零,你讲不清楚是原矩阵的零还是你修改之后的零。所以,一种方法就是先通过两个数组来记录该行该列上有没有零元素,等对矩阵遍历完之后再统一修改即可。
方法一:新开辟两个数组,记录每行和每列是否存在 0,空间复杂度为(m+n)
public class Solution {
public void setZeroes(int[][] matrix) {
if(matrix == null||matrix.length == 0||matrix[0].length == 0)
return;
boolean[] row=new boolean[matrix.length];
boolean[] col=new boolean[matrix[0].length];
//遍历matrix一次,记录有0的行和列
for(int i=0;i<matrix.length;i++)
{
for(int j=0;j<matrix[i].length;j++)
{
if(matrix[i][j] == 0)
{
row[i]=true;
col[j]=true;
}
}
}
//将有0的行清零
for(int i=0;i<row.length;i++)
{
if(row[i] == true)
{
for(int m=0;m<matrix[0].length;m++)
{
matrix[i][m]=0;
}
}
}
//将有0的列清零
for(int j=0;j<col.length;j++)
{
if(col[j] == true)
{
for(int n=0;n<matrix.length;n++)
{
matrix[n][j]=0;
}
}
}
}
}
方法二:对方法一的改进,利用matrix中的空间
如果matrix中有一个0,那么该row,col的行和列都为0,那么之后该行和列就能用来存储解法二的行列了。空降O(1)
matrix[row][k]用来存储第k列是否有0
matrix[k][col]用来存储第k行是否有0
public class Solution {
public void setZeroes(int[][] matrix) {
if(matrix == null||matrix.length == 0||matrix[0].length == 0)
return;
boolean firstzero=false;
int row=0;
int col=0;
//遍历matrix一次,找到第一个0的位置
for(int i=0;i<matrix.length;i++)
{
for(int j=0;j<matrix[i].length;j++)
{
if(matrix[i][j] == 0)
{
row=i;
col=j;
firstzero=true;
break;
}
}
}
if(firstzero == false)
return;
//遍历matrix,记录有0的行和列
for(int i=0;i<matrix.length;i++)
{
for(int j=0;j<matrix[i].length;j++)
{
if(matrix[i][j] == 0&&i!=row&&j!=col)
{
matrix[row][j]=0;
matrix[i][col]=0;
}
}
}
//遍历matrix,清0 注意:这里不用逐行逐列清0,要不会变得比较复杂。
for(int i=0;i<matrix.length;i++)
{
for(int j=0;j<matrix[i].length;j++)
{
if(i!=row&&j!=col)
if(matrix[i][col] == 0||matrix[row][j] == 0)
{
matrix[i][j]=0;
}
}
}
//将row,col行列清0
for(int i=0;i<matrix.length;i++)
{
matrix[i][col]=0;
}
for(int j=0;j<matrix[row].length;j++)
{
matrix[row][j]=0;
}
}
}