矩阵置零(Set Matrix Zeroes)题解
题目描述
给定一个 m x n的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法。
示例:
输入:
[[1,1,1],
[1,0,1],
[1,1,1]]
输出:
[[1,0,1],
[0,0,0],
[1,0,1]]
解题思路
使用标记数组技巧,通过两个辅助数组分别记录需要置零的行和列:
row[m]: 标记哪些行需要置零col[n]: 标记哪些列需要置零
算法步骤:
- 第一次遍历:标记所有0元素所在的行和列
- 第二次遍历:根据标记数组将对应行列置零
代码实现
#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<vector<int>> matrix = {{1,1,1},{1,0,1},{1,1,1}};
int m=matrix.size();
int n=matrix[0].size();
//标记数组
vector<bool> row(m,false);
vector<bool> col(n,false);
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(matrix[i][j]==0){
row[i]=true;
col[j]=true;
}
}
}
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(row[i]||col[j]){
matrix[i][j]=0;
}
}
}
//输出矩阵
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
cout<<matrix[i][j]<<" ";
}
cout<<endl;
}
}
执行过程演示
以输入 [[1,1,1],[1,0,1],[1,1,1]]为例:
第一步:标记阶段
- 遍历发现
matrix[1][1] = 0 - 标记
row[1] = true,col[1] = true
第二步:置零阶段
-
遍历所有元素,如果所在行或列被标记,则置零:
- 第1行所有元素:
row[1]为true → 全部置零 - 第1列所有元素:
col[1]为true → 全部置零
- 第1行所有元素:
最终结果:
1 0 1
0 0 0
1 0 1
复杂度分析
- 时间复杂度:O(m × n),需要遍历矩阵两次
- 空间复杂度:O(m + n),使用了两个标记数组
优化思路
如果需要O(1)空间复杂度,可以使用矩阵的第一行和第一列作为标记数组,但需要额外处理第一行和第一列本身的0元素情况。