73. Set Matrix Zeroes
Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in-place.
Example 1:
Input:
[
[1,1,1],
[1,0,1],
[1,1,1]
]
Output:
[
[1,0,1],
[0,0,0],
[1,0,1]
]
Example 2:
Input:
[
[0,1,2,0],
[3,4,5,2],
[1,3,1,5]
]
Output:
[
[0,0,0,0],
[0,4,5,0],
[0,3,1,0]
]
Follow up:
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?
Hint:
- If any cell of the matrix has a zero we can record its row and column number using additional memory. But if you don’t want to use extra memory then you can manipulate the array instead. i.e. simulating exactly what the question says.
- Setting cell values to zero on the fly while iterating might lead to discrepancies. What if you use some other integer value as your marker? There is still a better approach for this problem with 0(1) space.
- We could have used 2 sets to keep a record of rows/columns which need to be set to zero. But for an O(1) space solution, you can use one of the rows and and one of the columns to keep track of this information.
- We can use the first cell of every row and column as a flag. This flag would determine whether a row or column has been set to zero.
方法0:
思路:
根据follow up里面列出的提示,如果用O(m + n)的方法,就是记录一个row,col vector,每一个标记是否有0 出现过,最后遍历一次把出现过0的地方都换成0。
Complexity
Time Complexity: O(M×N) where M and N are the number of rows and columns respectively.
Space Complexity: O(M + N).
方法1:
官方题解: https://leetcode.com/problems/set-matrix-zeroes/solution/
grandyang: http://www.cnblogs.com/grandyang/p/4341590.html
思路:
但是如何用O(1)的方法呢?一开始的想法是遍历一遍,将每个非0位置改为1,一共遍历2次,计算每一行的累计和。如果小于m(列)或n(行),变为0。借用了tic-tac-toc的办法, 但是这个方法时间上不是很有效,需要遍历3遍。solution的解给出的更加简单。solution的第一种O(1)解法是遇见每一个0,将该行该列改为一个特殊数字,比如-100000。最后遍历一遍将所有特殊符号设为0。
- 先扫描第一行第一列,如果有0,则将各自的flag设置为true
- 然后扫描除去第一行第一列的整个数组,如果有0,则将对应的第一行和第一列的数字赋0
- 再次遍历除去第一行第一列的整个数组,如果对应的第一行和第一列的数字有一个为0,则将当前值赋0
- 最后根据第一行第一列的flag来更新第一行第一列
这里暂时用两个flag来标记第一行和第一列而不直接更新为0是因为,如果第一行第一列在一开始就被都set成0,那么之后遍历的时候,将查找不到之前存储的是否含有0的信息,会将所有数字都设为0.
易错点
- 中间两步不能包含第一行第一列
Complexity
Time complexity
Space complexity
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
bool zeroRow = false, zeroCol = false;
//
for (int i = 0; i < matrix.size(); i++){
if (matrix[i][0] == 0) zeroCol = true;
}
for (int j = 0; j < matrix[0].size(); j++){
if (matrix[0][j] == 0) zeroRow = true;
}
for (int i = 1; i < matrix.size(); i++){
for (int j = 1 ; j < matrix[0].size(); j++){
if (matrix[i][j] == 0) matrix[i][0] = matrix[0][j] = 0;
}
}
for (int i = 1; i < matrix.size(); i++){
for (int j = 1 ; j < matrix[0].size(); j++){
if (matrix[0][j] == 0 || matrix[i][0] == 0)
matrix[i][j] = 0;
}
}
if (zeroCol){
for (int i = 0; i < matrix.size(); i++) matrix[i][0] = 0;
}
if (zeroRow){
for (int j = 0; j < matrix[0].size(); j++) matrix[0][j] = 0;
}
return;
}
};