Zero Matrix:给定一个矩阵,将矩阵中0元素所在的行和列清零。
乍看这道题还是很简单的:遍历矩阵中的元素,如果出现0就将对应的行列清零。但是这样做是有问题的,当后续遍历到被清零的元素时,会继续清零,这样只要矩阵中有一个0,那么最终整个矩阵都会被清零。
所以我们必须进行两次遍历,第一次遍历对每个位置进行标记,第二次遍历才清零,这样需要的空间复杂度为O(MN)。
但是其实只需要知道需要将哪一行和哪一列清零就可以了,而不需要知道0元素的位置,所以只需要O(M + N)的空间复杂度就可以了。
class Solution {
public:
void setZeroes(vector<vector<int>> &matrix) {
vector<bool> vbRow(matrix.size(), false);
vector<bool> vbCol(matrix[0].size(), false);
for(size_t i = 0; i < matrix.size(); i++)
{
for(size_t j = 0; j < matrix[i].size(); j++)
{
if(matrix[i][j] == 0){
vbRow[i] = vbCol[j] = true;
}
}
}
for(size_t i = 0; i < vbRow.size(); i++)
{
if(vbRow[i]) matrix[i].assign(matrix[i].size(), 0);
}
for(size_t j = 0; j < vbCol.size(); j++)
{
if(vbCol[j]){
for(size_t i = 0; i < matrix.size(); i++)
{
matrix[i][j] = 0;
}
}
}
}
};
继续优化一下,我们可以使用原始矩阵的第0行和第0列来代替标志位的存储空间,这样步骤为:
- 判断第
0行和第0列中是否存在0元素,并记录在bRow0和bCol0中 - 遍历剩余的元素,将
0元素的行列号记录在第0行和第0列中 - 根据第
0行和第0列的信息,对矩阵其余行列进行清零 - 根据
bRow0和bCol0对第0行和第0列进行清零
class Solution {
public:
void setZeroes(vector<vector<int>> &matrix) {
bool bRow0 = false, bCol0 = false;
for(size_t i = 0; i < matrix.size(); i++)
{
if(matrix[i][0] == 0) bCol0 = true;
}
for(size_t j = 0; j < matrix[0].size(); j++)
{
if(matrix[0][j] == 0) bRow0 = true;
}
for(size_t i = 1; i < matrix.size(); i++)
{
for(size_t j = 1; j < matrix[i].size(); j++)
{
if(matrix[i][j] == 0){
cout << 1 << endl;
matrix[0][j] = matrix[i][0] = 0;
}
}
}
for(size_t i = 1; i < matrix.size(); i++)
{
if(matrix[i][0] == 0){
setRowZero(matrix, i);
}
}
for(size_t j = 1; j < matrix[0].size(); j++)
{
if(matrix[0][j] == 0){
setColZero(matrix, j);
}
}
if(bRow0){
setRowZero(matrix, 0);
}
if(bCol0){
setColZero(matrix, 0);
}
}
private:
void setRowZero(vector<vector<int>> &matrix, size_t row)
{
matrix[row].assign(matrix[row].size(), 0);
}
void setColZero(vector<vector<int>> &matrix, size_t col)
{
for(size_t i = 0; i < matrix.size(); i++)
{
matrix[i][col] = 0;
}
}
};
6840

被折叠的 条评论
为什么被折叠?



