【Set Matrix Zeros】cpp
题目:
Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place.
Follow up:
Did you use extra space?
A straight forward solution using O(mn) space is probably a bad idea.
A simple improvement uses O(m + n) space, but still not the best solution.
Could you devise a constant space solution?
代码:
class Solution { public: void setZeroes(vector<vector<int> > &matrix) { const size_t size_row = matrix.size(); const size_t size_col = matrix[0].size(); bool if_row0_has_zero = false; bool if_col0_has_zero = false; for (size_t col = 0; col < size_col; ++col){ if (matrix[0][col]==0){ if_row0_has_zero = true; break; } } for (size_t row = 0; row < size_row; ++row){ if (matrix[row][0]==0){ if_col0_has_zero = true; break; } } for (size_t row = 0; row < size_row; ++row){ for (size_t col = 0; col < size_col; ++col){ if (matrix[row][col]==0){ matrix[row][0] = 0; matrix[0][col] = 0; } } } for (size_t row = 1; row < size_row; ++row){ for (size_t col = 1; col < size_col; ++col){ if ( matrix[row][0]==0 || matrix[0][col]==0 ) matrix[row][col]=0; } } if (if_row0_has_zero) { for (size_t col = 0; col < size_col; ++col) matrix[0][col]=0; } if (if_col0_has_zero){ for (size_t row = 0; row < size_row; ++row) matrix[row][0]=0; } } };
Tips:
1. 算法时间复杂度上是O(n²)
2. 这里为了节省空间复杂度,用到的技巧是把第一行和第一列作为该行或该列是否含有0元素的标志位,这样就可以在常数空间内完成题目。
========================================================
第二次过这道题,思路比较清晰,代码也一次AC了。
class Solution { public: void setZeroes(vector<vector<int>>& matrix) { if (matrix.size()==0) return; // check first row bool first_row_zero = false; for ( int j=0; j<matrix[0].size(); ++j ) { if (matrix[0][j]==0) {first_row_zero=true;break;} } // check frist col bool first_col_zero = false; for ( int j=0; j<matrix.size(); ++j ) { if ( matrix[j][0]==0) {first_col_zero=true;break;} } // check remains for ( int i=1; i<matrix.size(); ++i ) { for ( int j=1; j<matrix[i].size(); ++j ) { if ( matrix[i][j]==0 ) { matrix[0][j] = 0; matrix[i][0] = 0; } } } // set row zeros for ( int i=1; i<matrix.size(); ++i ) { if ( matrix[i][0]==0 ) { for ( int j=1; j<matrix[i].size(); ++j ) matrix[i][j] = 0; } } // set col zeros for ( int j=1; j<matrix[0].size(); ++j ) { if ( matrix[0][j]==0 ) { for ( int i=1; i<matrix.size(); ++i ) matrix[i][j] = 0; } } if (first_row_zero) { for ( int j=0; j<matrix[0].size(); ++j ) matrix[0][j] = 0; } if ( first_col_zero) { for ( int i=0; i<matrix.size(); ++i ) matrix[i][0] = 0; } } };
这个代码大体上没有问题,但是在一个部分是可以优化的。就是set row zeros和set col zeros两个部分可以合成一个,改一版代码如下。
class Solution { public: void setZeroes(vector<vector<int>>& matrix) { if (matrix.size()==0) return; // check first row bool first_row_zero = false; for ( int j=0; j<matrix[0].size(); ++j ) { if (matrix[0][j]==0) {first_row_zero=true;break;} } // check frist col bool first_col_zero = false; for ( int j=0; j<matrix.size(); ++j ) { if ( matrix[j][0]==0) {first_col_zero=true;break;} } // check remains for ( int i=1; i<matrix.size(); ++i ) { for ( int j=1; j<matrix[i].size(); ++j ) { if ( matrix[i][j]==0 ) { matrix[0][j] = 0; matrix[i][0] = 0; } } } // set zeros for ( int i=1; i<matrix.size(); ++i ) { for ( int j=1; j<matrix[i].size(); ++j ) { if ( matrix[i][0]==0 || matrix[0][j]==0 ) matrix[i][j]=0; } } if (first_row_zero) { for ( int j=0; j<matrix[0].size(); ++j ) matrix[0][j] = 0; } if ( first_col_zero) { for ( int i=0; i<matrix.size(); ++i ) matrix[i][0] = 0; } } };
这样改版后,代码效率提升了。