Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place.
Did you use extra space?
A straight forward solution using O(mn) space is probably a bad idea.
A simple improvement uses O(m + n) space, but still not the best solution.
Could you devise a constant space solution?
Anwser 1: 利用额外O(m + n)空间
思路:建立行和列的含0标记,然后根据标记将相应的元素置0;
复杂度:O(mn)
Attention: 由于无法直接将matrix某列直接置0,注意置某行置某列的方法。
AC Code:
<span style="font-size:14px;">class Solution {
public:
void setZeroes(vector<vector<int> > &matrix) {
//额外空间O(m+n) 即标记m行和n列是否有含0的元素
int row = matrix.size();
if(row < 1) return;
int col = matrix[0].size();
//标记行和列是否含0元素
vector<bool> rowRecoder(row);
vector<bool> colRecoder(col);
//初始化行列的标记
for(int i = 0; i < row; i++)
{
for(int j = 0; j < col; j++)
{
if(matrix[i][j] == 0)
{
rowRecoder[i] = true;
colRecoder[j] = true;
}
}
}
for(int i = 0; i < row; i++)
{
for(int j = 0; j < col; j++)
{
if(rowRecoder[i]) matrix[i][j] = 0;
else if(colRecoder[j]) matrix[i][j] = 0;
}
}
}
};</span>
Anwser 2: 使用常数空间
常数空间的话,第一可以考虑是不是固定数量的几个变量能搞定;否则可以考虑是不是问题本身已经提供了足够的空间。
思路:
这道题属于后者,就是利用矩阵的第一行和第一列来作为辅助空间使用。不用开辟新的存储空间。方法就是:
1.先确定第一行和第一列是否需要清零
即,看看第一行中是否有0,记下来。也同时记下来第一列中有没有0。
2.扫描剩下的矩阵元素,如果遇到了0,就将对应的第一行和第一列上的元素赋值为0
这里不用担心会将本来第一行或第一列的1改成了0,因为这些值最后注定要成为0的(确定A[i][j]为0,则A[0][j]和A[i][0]为0)。
3.根据第一行和第一列的信息,已经可以将剩下的矩阵元素赋值为结果所需的值了
即,拿第一行为例,如果扫描到一个0,就将这一列都清0.
4.根据1中确定的状态,处理第一行和第一列。
如果最开始得到的第一行中有0的话,就整行清零。同理对列进行处理。
Attention:
1.注意第二步和第三步,尤其是第三步的赋值操作,判断到无论是第i行中有0,或者第j列含0,都可以将A[i][j]置0(根据题目规则)。
if(matrix[0][ci] == 0 || matrix[ri][0] == 0)
{
matrix[ri][ci] = 0;
}
2.判断到第1行或者第一列中含有0值,即可以break 无须继续判断。
复杂度:O(mn)
AC Code:
<span style="font-size:14px;">class Solution {
public:
void setZeroes(vector<vector<int> > &matrix) {
int row = matrix.size();
int col = matrix[0].size();
if(row < 1 || col < 1) return;
bool firstRowhasZero = false;
bool firstColhasZero = false;
//using first row and col as storage
//1.search zero in first row and col to determin it's own status
for(int ci = 0; ci < col; ci++)
{
if(matrix[0][ci] == 0)
{
firstRowhasZero = true;
break;
}
}
for(int ri = 0; ri < row; ri++)
{
if(matrix[ri][0] == 0)
{
firstColhasZero = true;
break;
}
}
//2.search zeros in other position to sign the first row and col 搜索除第一行和第一列外的其他元素
for(int ri = 1; ri < row; ri++)
{
for(int ci = 1; ci < col; ci++)
{
if(matrix[ri][ci] == 0)
{
matrix[ri][0] = 0;
matrix[0][ci] = 0;
}
}
}
//3.set zeroes in other positions according to first col and row
for(int ri = 1; ri < row; ri++)
{
for(int ci = 1; ci < col; ci++)
{
if(matrix[0][ci] == 0 || matrix[ri][0] == 0)
{
matrix[ri][ci] = 0;
}
}
}
//4.set zeroes for first row and col
if(firstRowhasZero)
{
for(int ci = 0; ci < col; ci++)
{
matrix[0][ci] = 0;
}
}
if(firstColhasZero)
{
for(int ri = 0; ri < row; ri++)
{
matrix[ri][0] = 0;
}
}
return;
}
};</span>