解答一:
cpp
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
//O(mn)额外空间,直白思想:找个和matrix一样形状的数组做vis标记数组
//如果遇到了0,那就vis[i][j]=1,表明这个数组位置已经被用过了
//不会出现:如示例1中,遍历到第二行第二列0时,把第二行和第二列所有数字变成0
//下一个遍历第二行第三列,已经在上一步中变成0了
//你要是不做标记,那也会把第三列所有数变成0,那就错了
//但是,注意示例2又提醒了我们另一种情况
//当两个0在同一行时候,如果你在遍历到第二个0的时候,vis是1
//那么他就会跳过这个0,不把第四列变成0了
//所以在进行vis更新前,我们需要判断一下这个数是不是原本就是0
//如果原本就是0的话,vis就依旧是0
int m=matrix.size();
int n=matrix[0].size();
vector<vector<int>> vis(m,vector<int>(n));
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(matrix[i][j]==0&&vis[i][j]==0){
for(int k=0;k<n;k++){
if(matrix[i][k]!=0){
vis[i][k]=1;
}
matrix[i][k]=0;
}
for(int k=0;k<m;k++){
if(matrix[k][j]!=0){
vis[k][j]=1;
}
matrix[k][j]=0;
}
}
}
}
return;
}
};
时间复杂度:O(mn)
空间复杂度:O(mn)
解答二:
cpp
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
//O(m+n)额外空间:一个数组存行位置,一个数组存列位置
int mm=matrix.size();
int nn=matrix[0].size();
vector<int> m(mm);
vector<int> n(nn);
for(int i=0;i<mm;i++){
for(int j=0;j<nn;j++){
//把所有是0的数的行位置和列位置记录下来
if(matrix[i][j]==0){
m[i]=n[j]=1;
}
}
}
for(int i=0;i<mm;i++){
for(int j=0;j<nn;j++){
if(m[i]!=0||n[j]!=0){
//只要行有0或者列有0就直接变0
matrix[i][j]=0;
}
}
}
}
};
时间复杂度:O(mn)
空间复杂度:O(m+n)