题目
给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法。
示例 1:
输入:
[
[1,1,1],
[1,0,1],
[1,1,1]
]
输出:
[
[1,0,1],
[0,0,0],
[1,0,1]
]
示例 2:
输入:
[
[0,1,2,0],
[3,4,5,2],
[1,3,1,5]
]
输出:
[
[0,0,0,0],
[0,4,5,0],
[0,3,1,0]
]
进阶:
一个直接的解决方案是使用 O(mn) 的额外空间,但这并不是一个好的解决方案。
一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。
你能想出一个常数空间的解决方案吗?
分析
先考虑 O(m + n) 额外空间的方法:因为一行/列中只要有一个是 0,那么这一行/列都是0。可以建立长度 m + n 的数组记录该行/该列是否有 0,然后统一赋值即可。
接下来考虑 O(1) 额外空间的方法:可以用 记录行和列中是否含有 0。现在只需要遍历从
开始的元素。如果
, 那么将
都置为 0。最后再统一赋值即可,这样就完成了从
开始的所有元素的赋值。
但是还有一个细节需要关注:完成上述步骤后,还需要处理 本身为 0 的情况。所以先用两个布尔型变量记录。最后再进行赋值。
代码
class Solution {
public void setZeroes(int[][] matrix) {
if (matrix == null || matrix.length == 0) return;
if (matrix[0] == null || matrix[0].length == 0) return;
int rows = matrix.length, cols = matrix[0].length;
boolean rowFlag = false, colFlag = false;
for (int j = 0; j < cols; j++) {
if (matrix[0][j] == 0) {
colFlag = true;
break;
}
}
for (int i = 0; i < rows; i++) {
if (matrix[i][0] == 0) {
rowFlag = true;
break;
}
}
for (int i = 1; i < rows; i++) {
for (int j = 1; j < cols; j++) {
if (matrix[i][j] == 0) {
matrix[i][0] = 0;
matrix[0][j] = 0;
}
}
}
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;
}
}
}
if (rowFlag) {
for (int i = 0; i < rows; i++) matrix[i][0] = 0;
}
if (colFlag) {
for (int j = 0; j < cols; j++) matrix[0][j] = 0;
}
}
}