问题:给定一矩阵,将矩阵中所以元素0 所在的行、列都置为0。要求最后用O(1)的空间复杂度。
分析:
问题的难点在于如何区分矩阵中原有的0和经设置而变成的0,也就是说,我们在设置0所在的行列时,可能会遇到原来就有的0,如果我们将这些原有的0进行保存,那显然就不满足空间复杂度的要求了。那么就只能在矩阵本身上打主意了。想想我们做过的一个题:First Missing Positive,在该题目里,我们在数组本身上做文章。这里我们想想能不能用同样的套路解决问题呢?这里我们利用第一行,第一列(四个边界吧,行列各取一个都行)。
1)记录第一行是否存在0
2)记录第一列是否存在0
3)遍历列矩阵中其他行列的元素A[i,j] ,若为0, 则对应的 A[0][j] = 0, A[i][0] = 0.
4)遍历矩阵中的其他行列的元素A[i,j], 若 A[0][j] = 0 || A[i][0] = 0, 则 A[i][j] = 0
5)若第一行有0存在,则将正行置为0, 第一列同样。
void setZeroes(vector<vector<int> > &matrix) { int rows = matrix.size(); if(rows == 0 || matrix[0].size() == 0) return; int cols = matrix[0].size(); //record the message about 0 of first column and firs row. bool rzero = false; bool czero = false; //first row. for (int i = 0; i < cols; ++i) { if(matrix[0][i] == 0){ rzero = true; break; } } //first col for (int j = 0; j < rows; ++j) { if(matrix[j][0] == 0){ czero = true; break; } } // mapping other 0s to the first col and first row. for (int i = 1; i < rows; ++i) for (int j = 1; j < cols; ++j) { if(matrix[i][j] == 0) { matrix[0][j] = 0; matrix[i][0] = 0; } } // using the map message to set the other items. for (int i = 1; i < rows; ++i) for(int j = 1; j < cols; ++j) { if (matrix[i][0] == 0 || matrix[0][j] == 0) { matrix[i][j] = 0; } } //set the first col and first row if(rzero) for (int i = 0; i < cols; ++i) { matrix[0][i] = 0; } if(czero) for(int j = 0; j < rows; ++j) matrix[j][0] = 0; }