题目:
给定一个 mxn 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法**。**
示例 1:

输入: matrix = [[1,1,1],[1,0,1],[1,1,1]]
输出:[[1,0,1],[0,0,0],[1,0,1]]
示例 2:

输入: matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
输出:[[0,0,0,0],[0,4,5,0],[0,3,1,0]]
提示:
-
m == matrix.length -
n == matrix[0].length -
1 <= m, n <= 200 -
-2^31 <= matrix[i][j] <= 2^31 - 1
题解:
法一:空间复杂度O(m+n)
思路:
遍历一次矩阵,记录下所有0元素所在的行号和列号,然后第二次遍历时,只要当前位置的行号或列号被标记过,就把该位置置为0。
标记信息可以用两个布尔数组实现:一个长度为 m 的 row 数组,row[i] = true 表示第 i 行需要清零;另一个长度为 n 的 col 数组,col[j] = true 表示第 j 列需要清零。
代码:
cpp
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
int m=matrix.size();
int n=matrix[0].size();
vector <int> row(m),col(n);
//第一次遍历:标记需要清零的行和列
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(matrix[i][j]==0) row[i]=col[j]=true;
}
}
//第二次遍历:根据标记修改矩阵
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(row[i]==true||col[j]==true) matrix[i][j]=0;
}
}
}
};
法二:空间复杂度O(1)
思路:
借用矩阵第一行和第一列作为标记数组。
详细步骤:
步骤 1:检查第一行和第一列是否原本包含0
- 遍历就第一行,如果有元素为 0,则设置 firstRowHasZero = true。
- 遍历第一列,如果有元素为 0,则设置 firstColHasZero = true。
步骤 2:用第一行和第一列作为标记数组
遍历矩阵的内部区域(即下标从 1 到 m-1 的行,1 到 n-1 的列):
- 如果 matrix[i][j] == 0,则:
- 将 matrix[i][0] 设为 0 ------ 标记第 i 行需要清零
- 将 matrix[0][j] 设为 0 ------ 标记第 j 列需要清零
步骤 3:根据标记清零内部区域
再次遍历内部区域(即下标从 1 到 m-1 的行,1 到 n-1 的列):
如果 matrix[i][0] == 0 或 matrix[0][j] == 0,则把 matrix[i][j] 设为 0。
步骤 4:处理第一行和第一列
- 如果 firstRowHasZero 为true,则将第一行的所有元素设为 0。
- 如果 firstColHasZero 为true,则将第一列的所有元素设为 0。
代码:
cpp
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
int m=matrix.size();
int n=matrix[0].size();
bool firstRowHasZero=false;
bool firstColHasZero=false;
//步骤1:检查第一行和第一列是否原本包含0
for(int j=0;j<n;j++){
if(matrix[0][j]==0) firstRowHasZero=true;
}
for(int i=0;i<m;i++){
if(matrix[i][0]==0) firstColHasZero=true;
}
//步骤2:用第一行和第一列作为标记数组
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
if(matrix[i][j]==0){
matrix[i][0]=0;
matrix[0][j]=0;
}
}
}
//步骤3:根据标记清零内部区域
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
if(matrix[i][0]==0||matrix[0][j]==0)
matrix[i][j]=0;
}
}
//步骤4:处理第一行和第一列
if(firstColHasZero){
for(int i=0;i<m;i++) matrix[i][0]=0;
}
if(firstRowHasZero){
for(int j=0;j<n;j++) matrix[0][j]=0;
}
}
};