给定一个 mx
n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法**。**
cpp
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
int m = matrix.size();
int n = matrix[0].size();
// 标记第一行和第一列是否需要置零
bool firstRowZero = false, firstColZero = false;
// 检查第一列是否有零
for (int i = 0; i < m; ++i) {
if (matrix[i][0] == 0) {
firstColZero = true;
break;
}
}
// 检查第一行是否有零
for (int j = 0; j < n; ++j) {
if (matrix[0][j] == 0) {
firstRowZero = true;
break;
}
}
// 用第一行和第一列作为标记
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;
}
}
}
// 根据标记置零
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 (firstColZero) {
for (int i = 0; i < m; ++i) {
matrix[i][0] = 0;
}
}
// 处理第一行
if (firstRowZero) {
for (int j = 0; j < n; ++j) {
matrix[0][j] = 0;
}
}
}
};
标记需要置零的行和列:
我们不能直接修改矩阵,因为这样会影响后续的判断。因此,我们可以利用矩阵的第一行和第一列作为标记,用来记录哪些行和列需要置零。
具体步骤:
遍历矩阵,找到为零的元素,将对应的行和列的第一个元素置为零(即标记)。
再次遍历矩阵,使用标记的信息将对应的行和列置为零。
需要额外的变量来记录第一行和第一列是否需要置零,因为这两个被用作标记列。
时间复杂度和空间复杂度:
时间复杂度:O(m * n),需要遍历两次矩阵。
空间复杂度:O(1),只使用了常数额外空间。