题目:
给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法。
示例 1:
输入:
[
[1,1,1],
[1,0,1],
[1,1,1]
]
输出:
[
[1,0,1],
[0,0,0],
[1,0,1]
]
示例 2:
输入:
[
[0,1,2,0],
[3,4,5,2],
[1,3,1,5]
]
输出:
[
[0,0,0,0],
[0,4,5,0],
[0,3,1,0]
]
进阶:
- 一个直接的解决方案是使用 O(mn) 的额外空间,但这并不是一个好的解决方案。
- 一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。
- 你能想出一个常数空间的解决方案吗?
每天更新一道python or C++ leetcode题,力求讲解清晰准确,客官们可以点赞或者关注。
进阶O(m*n) 方法:重新构建一个m*n的数组,先把0填进去,然后把0所在的行和列填为0,然后把剩下的数填入相对应的位置上。
进阶O(m+n)方法:两个数组,bool1[m] 和 bool2[n] 分别存某行有零,后者某列有零。之后根据数组值将原矩阵相应位置置零。额外空间O(m + n)。比如bool1[0]为true代表0行有0,bool2[3]为true代表index为3的列有0;
代码:(仅c++)
class Solution {
public:
void setZeroes(vector<vector<int> > &matrix) {
int len1 = matrix.size();
if (len1 == 0) return ;
int len2 = matrix[0].size();
if (len2 == 0) return ;
vector<bool > row(len1), col(len2);
for (int i = 0; i < len1; i++)
for (int j = 0; j < len2; j++)
{
if (matrix[i][j] == 0)
{
row[i] = true; col[j] = true;
}
}
for (int i = 0; i < len1; i++)
for (int j = 0; j < len2; j++)
{
if (row[i] == true)
matrix[i][j] = 0;
else if (col[j] == true)
matrix[i][j] = 0;
}
return ;
}
};
方法三(常量空间):
先扫描数组记下0,0的位置(行和列),然后再次扫描数组,检索每个元素,当所在行数与其中任意一个0的行数相同时便置为0,当所在行数与其中任意一个0的列数相同时便置为0。
Python:
class Solution:
def setZeroes(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: void Do not return anything, modify matrix in-place instead.
"""
pos_list = []
col = len(matrix[0])
row = len(matrix)
for i in range(row):
for j in range(col):
if matrix[i][j] == 0:
#记下0的位置
pos_list.append([i, j])
for cor in pos_list:#遍历所有的0坐标
temrow = cor[0]#横坐标
temcol = cor[1]#纵坐标
#把行和列置为0
for i in range(row):
matrix[i][temcol] = 0
for j in range(col):
matrix[temrow][j] = 0
C++(如果你认为上面那种不是常量空间,接下来的这种解法保证了常数空间,因为我们只记录最靠近右下角的0的位置.)
class Solution {
public:
void setZeroes(vector<vector<int> > &matrix) {
int len1 = matrix.size();
if (len1 == 0) return ;
int len2 = matrix[0].size();
if (len2 == 0) return ;
int row = -1, col = -1;
for (int i = 0; i < len1; i++)
for (int j = 0; j < len2; j++)
{
if (matrix[i][j] == 0)
{
row = i; col = j;//记录的是最靠近右下角的0的位置
}
}
if (row == -1) return;
for (int i = 0; i < len1; i++)
for (int j = 0; j < len2; j++)
{
if (matrix[i][j] == 0 && i != row && j != col)//如果有0项,但不是我们最后记录的那一个
{
matrix[i][col] = 0;
matrix[row][j] = 0;
}
}
for (int i = 0; i < len1; i++)
for (int j = 0; j < len2; j++)
{
if (i != row && j != col)
{
if (matrix[i][col] == 0 )
matrix[i][j] = 0;
else if (matrix[row][j] == 0)
matrix[i][j] = 0;
}
}
int index = -1;
while(++index < len1) matrix[index][col] = 0;
index = -1;
while(++index < len2) matrix[row][index] = 0;
return ;
}
};
C++的解法比较曲折,感兴趣的朋友可以自己尝试追踪一下轨迹理解一下代码,(这种解法是绝对符合题意的)