题目描述:给 m × n 的矩阵,若一个元素为0,则将其所在行列的所有元素置0,原地操作。
分析:显然重新申请一个 m × n 的矩阵,遍历原矩阵元素,将每一个为0的元素所在行列置0即可;或者用O( m + n )的空间设置两个bool数组,记录每行每列是否存在0。时间复杂度O(m × n ),空间O( m + n ),见代码一。
代码一:
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
int m = matrix.size();
int n = matrix[0].size();
vector<bool> r(m, false);
vector<bool> c(n, false);
//标记应该置0的行列
for (int i = 0; i < m; i ++)
for (int j = 0; j < n; j ++)
if (matrix[i][j] == 0)
r[i] = c[j] = true;
//对应行置0
for (int i = 0; i < m; i ++)
if (r[i])
fill(&matrix[i][0], &matrix[i][0] + n, 0);
//对应列置0,两种写法
for (int j = 0; j < n; j ++)
if (c[j])
{
for (int i = 0; i < m; i ++)
matrix[i][j] = 0;
}
}
};
代码二:复用第一行和第一列,其实就是将第一行第一列作为指示向量,时间复杂度O(m × n ),空间O(1)。
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
int m = matrix.size();
int n = matrix[0].size();
bool rz = false;
bool cz = false;
for (int i = 0; i < n; i ++) //检查第一行是否有0
if (matrix[0][i] == 0)
{
rz = true;
break;
}
for (int i = 0; i < m; i ++)
if (matrix[i][0] == 0)
{
cz = true;
break;
}
//第一行第一列以外的位置找到0,则将对应的第一行该列与第一列该行置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;
}
//遍历每个元素,只检查其对应第一行第一列是否为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;
//检查第一行第一列是否原本有元素为0
if (rz)
{
for (int i = 0; i < n; i ++)
matrix[0][i] = 0;
}
if (cz)
{
for (int i = 0; i < m; i ++)
matrix[i][0] = 0;
}
}
};