73. Set Matrix Zeroes
仅供自己学习
思路:
第一个O(M+N)的空间复杂度。因为是原地算法,所以当我们根据0的位置更改为0后,我们再次遍历到0就会无法判断原来就是0还是更改后为0的。所以需要一个M*N的数据结构来记录原来为0的位置。
第一种 copy一个matrix,然后遍历copy的,如果有0就在matrix更改即可。
代码:
1 class Solution { 2 public: 3 void setZeroes(vector<vector<int>>& matrix) { 4 if(matrix.size()==0||matrix[0].size()==0) return; 5 vector<vector<int>> newM(matrix); 6 const int R = matrix.size(), C = matrix[0].size(); 7 for(int r=0;r<R;++r){ 8 for(int c=0;c<C;++c){ 9 if(newM[r][c] ==0 ){ 10 for(int j=0; j<C ;++j) matrix[r][j]=0; 11 for(int i=0;i<R ;++i) matrix[i][c]=0; 12 } 13 } 14 } 15 } 16 };
上面这种是边遍历边改。还有一种是全部遍历完再更改。每次遍历到0就存入队列,之后再取出来全部化0即可。
1 class Solution { 2 public: 3 void setZeroes(vector<vector<int>>& matrix) { 4 if(matrix.size()==0||matrix[0].size()==0) return; 5 const int R=matrix.size(),C=matrix[0].size(); 6 queue<pair<int,int>> q; 7 for(int r = 0; r<R; ++r){ 8 for(int c = 0; c<C; ++c){ 9 if(matrix[r][c]==0) q.push({r,c}); 10 } 11 } 12 13 while(!q.empty()){ 14 auto temp=q.front();q.pop(); 15 for(int j=0;j<C; ++j) matrix[temp.first][j]=0; 16 for(int i= 0; i < R; ++i)matrix[i][temp.second]=0; 17 } 18 } 19 };
另一种是M+N空间复杂度的方法。
用一个M长度的数组和N长度的数组存为0的位置。然后再遍历,更改为0的条件是 M[ i ]||N[ j ]。为什么只要求一个为1即可。这样才能把一行或者一列的置0。例如M[2]=N[3]=1,那么每次行数增加,列数增加到3时才能将一列的置0,否则只能将一行置零。
代码:
1 class Solution { 2 public: 3 void setZeroes(vector<vector<int>>& matrix) { 4 if(matrix.size()==0||matrix[0].size()==0) return; 5 const int R=matrix.size(),C=matrix[0].size(); 6 vector<int> N(R), M(C); 7 for(int r = 0; r<R; ++r){ 8 for(int c = 0; c<C; ++c){ 9 if(matrix[r][c]==0) N[r]=M[c]=1; 10 } 11 } 12 for(int i=0;i<R;++i){ 13 for(int j=0;j<C;++j){ 14 if(N[i]||M[j]) matrix[i][j]=0; 15 } 16 } 17 } 18 };
如果我们将矩阵 第一行第一列当作上面的两个N,M数组,就能达成O(1)的复杂度,但是有个问题就是第一行第一列改成0后那么如何判断他原来有没有0呢?所以我们用两个BOOL变量用来存储,第一行第一列有0就true,最后根据是否为true来决定是否将所有第一列和第一行元素置0。
这样做对的原因是,如果第一行,第一列没有0,那么我们在某个位置找到0后,例如[2][3],那么[0][3]和[2][0]会被置0,而我们题目要求时第二行第三列都会置0,所以[0][3],[2][0]提前置零并不会有问题。如果第一行,第一列有0,最后再把第一行,第一列置0同样不会影响结果。
代码:
1 class Solution { 2 public: 3 void setZeroes(vector<vector<int>>& matrix) { 4 if(matrix.size()==0||matrix[0].size()==0) return; 5 const int R=matrix.size(),C=matrix[0].size(); 6 bool flag_row0=false,flag_col0=false; 7 for(int i=0;i<C;++i){ 8 if(matrix[0][i]==0) flag_row0=true; 9 } 10 for(int j=0;j<R;++j){ 11 if(matrix[j][0]==0) flag_col0=true; 12 } 13 for(int i=1;i<R;++i){ 14 for(int j=1;j<C;++j){ 15 if(matrix[i][j]==0) matrix[0][j]=matrix[i][0]=0; 16 } 17 } 18 for(int i=1;i<R;++i){ 19 for(int j=1;j<C;++j){ 20 if(!matrix[0][j]||!matrix[i][0]) matrix[i][j]=0; 21 } 22 } 23 if(flag_row0){ 24 for(int i=0;i<C;++i) matrix[0][i]=0; 25 } 26 if(flag_col0){ 27 for(int i=0;i<R;++i) matrix[i][0]=0; 28 } 29 } 30 };

浙公网安备 33010602011771号