题目
编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。
思路
模拟法:使用矩阵的第一行和第一列来存储标记,若该行/列具有标记,则将该行/列清零。因为使用到第一行和第一列来存储标记,所以要额外为第一行和第一列设置标记
步骤
- 为第一行和第一列设置标记,标记为真代表有0
- 检查第一行,第一列有无0,若有,则将其标记设置为true
- 遍历矩阵,若某元素为0,则将对应行和列的标记设置为0
- 再次遍历矩阵,根据标记,将对应行和列清零
- 处理第一行和第一列,若标记为真,则将其清零(不能在第2步就将第一行和第二行清零,因为这样会导致整个矩阵为0)
笔记
- 二维数组行和列的长度
rows = matrix.size() columns = matrix[0].size()
- 使用vector创建指定行和列的二维数组
vector<vector<int>> array(rows, vector<int>(columns));
代码
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
int m = matrix.size();
int n = matrix[0].size();
bool row_flag = false, column_flag = false;//行和列的标记
//检查第一行有无0
for(int i = 0; i < n; i++){
if(matrix[0][i] == 0){
row_flag = true;
break;
}
}
//检查第一列有无0
for(int i = 0; i < m; i++){
if(matrix[i][0] == 0){
column_flag = true;
break;
}
}
//为元素为0所在的行和列打上标记
for(int i = 1; i < m; i++){
for(int j = 1; j < n; j++){
if(matrix[i][j] == 0){
matrix[0][j] = 0;
matrix[i][0] = 0;
}
}
}
//清空带标记的行和列
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;
}
}
}
//检查第一行和第一列
if(row_flag){
for(int i = 0; i < n; i++){
matrix[0][i] = 0;
}
}
if(column_flag){
for(int i = 0; i < m; i++){
matrix[i][0] = 0;
}
}
}
};
复杂度分析
时间复杂度O(mn)
空间复杂度O(1)