4. Matrix zeroing
subject
Given a matrix of m x n, if an element is 0, all elements in its row and column are set to 0. Please use the in place algorithm.
Advanced:
An intuitive solution is to use the extra space of O (m, n), but this is not a good solution.
A simple improvement is to use the additional space of O(m + n), but this is still not the best solution.
Can you think of a solution that uses only constant space?
- m == matrix.length
- n == matrix[0].length
- 1 <= m, n <= 200
- -2^31 <= matrix[i][j] <= 2^31 - 1
4.0 violence (using a lot of extra space)
An additional two-dimensional array is used for zeroing operation, which can avoid some problems caused by zeroing the original array
void setDataZeroes(vector<vector<int>>& data, int row, int col) { for (int i = 0; i < data[0].size(); i++) data[row][i] = 0; for (int i = 0; i < data.size(); i++) data[i][col] = 0; } void setZeroes0(vector<vector<int>>& matrix) { int rowSize = matrix.size(); int colSize = matrix[0].size(); vector<vector<int>> data(rowSize, vector<int>(colSize, 1)); for (int i = 0; i < rowSize; i++) //Copy a matrix to data for (int j = 0; j < colSize; j++) data[i][j] = matrix[i][j]; for (int i = 0; i < rowSize; i++) //Zero data for (int j = 0; j < colSize; j++) if (matrix[i][j] == 0) setDataZeroes(data, i, j); for (int i = 0; i < rowSize; i++) //Copy the zeroed data to the matrix for (int j = 0; j < colSize; j++) matrix[i][j] = data[i][j]; }
- Time complexity: O (m, n)
- Space complexity: O (m, n)
4.1. Improving violence
Use two one-dimensional arrays, one to record which rows should be zeroed and the other to record which columns should be zeroed
void setZeroes1(vector<vector<int>>& matrix) { vector<int> data1(matrix.size(), 0); vector<int> data2(matrix[0].size(), 0); for (size_t i = 0; i < matrix.size(); i++) //Which rows and columns of the record are all zeros { for (size_t j = 0; j < matrix[i].size(); j++) { if (matrix[i][j] == 0) { data1[i] = 1; data2[j] = 1; } } } for (size_t i = 0; i < data1.size(); i++) //Zero row { if (data1[i] == 0)continue; for (size_t j = 0; j < matrix[0].size(); j++) { matrix[i][j] = 0; } } for (size_t i = 0; i < data2.size(); i++) //Zeroing columns { if (data2[i] == 0)continue; for (size_t j = 0; j < matrix.size(); j++) { matrix[j][i] = 0; } } }
- Time complexity: O (m, n)
- Spatial complexity: O (m + n)
4.2. Change to violence
No extra space is used to record which rows and columns should be zeroed. How to mark them? Of course, the original array is used to mark them
Suppose that the middle number of an array of 3 * 3 is 0, how to mark its position?
Setting [0,1] to zero means that the second column should be set to zero
Setting [1,0] to zero means that the second line should be set to zero
Because it is a sequential traversal, setting these two numbers to zero will not affect the judgment of setting zero as a whole
Another problem is that if the first row has zero but the first column has no zero, the first number will be set to zero, resulting in misjudgment. Therefore, two additional variables should be used to judge whether the first row and the first column are set to zero
void setZeroes3(vector<vector<int>>& matrix) { bool firstRow = false, //Used to mark whether the first row and column should be set to zero firstCol = false; int rowSize = matrix.size(); int colSize = matrix[0].size(); for (int i = 0; i < rowSize; i++) for (int j = 0; j < colSize; j++) //Mark all rows and columns that should be zeroed if (!matrix[i][j]) { if (!i)firstRow = true; if (!j)firstCol = true; matrix[i][0] = 0; matrix[0][j] = 0; } for (int i = 1; i < rowSize; i++) //Zero the non first row and non first column first for (int j = 1; j < colSize; j++) if (!matrix[i][0] || !matrix[0][j]) matrix[i][j] = 0; if (firstRow) for (int i = 0; i < colSize; i++) matrix[0][i] = 0; if (firstCol) for (int i = 0; i < rowSize; i++) matrix[i][0] = 0; }
- Time complexity: O (m, n)
- Space complexity: O (1)
4.3 final improvement
Blogger here to explain that the above is my limit
Careful friends may find a problem. The first number of the above method is not used. If you want to be picky, you can use the first number to indicate whether the first row (or column) should be set to zero, and then use only one variable to represent another column (or row), so that the extra space is true. 1.