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.
click to show follow up.
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?
新建矩阵法
复杂度
时间 O(NM) 空间 O(NM)
思路
最简单的方法就是建一个同样大小的矩阵,在原矩阵中遇到一个0,就将新矩阵的行和列设为0
首行首列暂存法
复杂度
时间 O(NM) 空间 O(1)
思路
实际上,我们只需要直到哪些行,哪些列需要被置0就行了,最简单的方法就是建两个大小分别为M和N的数组,来记录哪些行哪些列应该被置0。那有没有可能不用额外空间呢?我们其实可以借用原矩阵的首行和首列来存储这个信息。这个方法的缺点在于,如果我们直接将0存入首行或首列来表示相应行和列要置0的话,我们很难判断首行或者首列自己是不是该置0。这里我们用两个boolean变量记录下首行和首列原本有没有0,然后在其他位置置完0后,再单独根据boolean变量来处理首行和首列,就避免了干扰的问题。
代码
public class Solution {
public void setZeroes(int[][] matrix) {
if(matrix.length == 0) return;
boolean firstRowZero = false, firstColZero = false;
// 记录哪些行哪些列需要置0,并判断首行首列是否需要置0
for(int i = 0; i < matrix.length; i++){
for(int j = 0; j < matrix[0].length; j++){
if(i != 0 && j != 0 && matrix[i][j] == 0){
matrix[i][0] = 0;
matrix[0][j] = 0;
} else if (matrix[i][j] == 0){
// 如果首行或首列出现0,则标记其需要置0,否则沿用上次值
firstRowZero = i == 0 ? true : firstRowZero;
firstColZero = j == 0 ? true : firstColZero;
}
}
}
// 将除首行首列的位置置0
for(int i = 1; i < matrix.length; i++){
for(int j = 1; j < matrix[0].length; j++){
if(matrix[0][j] == 0 || matrix[i][0] == 0){
matrix[i][j] = 0;
}
}
}
// 如果必要,将首列置0
for(int i = 0; firstColZero && i < matrix.length; i++){
matrix[i][0] = 0;
}
// 如果必要,将首行置0
for(int j = 0; firstRowZero && j < matrix[0].length; j++){
matrix[0][j] = 0;
}
}
}