leetcode Set Matrix Zero

class Solution {
public:
    void setZeroes(vector<vector<int> > &matrix) {
        int h = matrix.size();
        if(h == 0){
            return;
        }
        int w = matrix[0].size();
        if(w == 0){
            return;
        }
        for(int i = 0; i < h; ++i){
            for(int j = 0; j < w; ++j){
                if(matrix[i][j] == 0){
                    for(int k = 0; k < w; ++k){
                        matrix[i][k] = 0;
                    }
                    break;
                }
            }
        }
        for(int i = 0; i < w; ++i){
            for(int j = 0; j < h; ++j){
                if(matrix[i][j] == 0){
                    for(int k = 0; k < h; ++k){
                        matrix[k][i] = 0;
                    }
                }
                break;
            }
        }
    }
};

上述解法错误,因为第一个二重循环将所有含有0的行置为全0,而第二个二重循环将所有列清零的依据是,该列中至少有一个零元素,而实际上,引起这一列清零的不一定是原矩阵中的零,而是第一个二重循环置的零;
同理在矩阵中每遇到一个元素就更新其行or列也会遇到相似的问题
下面是一个跑的很慢但是Accepted的solution:

class Solution {
public:
    void setZeroes(vector<vector<int> > &matrix) {
        bool firstColumnZero = false, firstRowZero = false;
        int h = matrix.size();
        if(h == 0){
            return;
        }
        int w = matrix[0].size();
        if(w == 0){
            return;
        }
        for(int i = 0; i < w; ++i){
            if(matrix[0][i] == 0){
                firstRowZero = true;
                break;
            }
        }
        for(int i = 0; i < h; ++i){
            if(matrix[i][0] == 0){
                firstColumnZero = true;
                break;
            }
        }
        //didn't modify any of the elements in matrix 
        for(int i = 1; i < h; ++i){
            for(int j = 1; j < w; ++j){
                if(matrix[i][j] == 0){
                    matrix[i][0] = 0;
                    matrix[0][j] = 0;
                }
            }
        }
        for(int i = 1; i < w; ++i){
            if(matrix[0][i] == 0){
                //column i clear to zero
                for(int k = 0; k < h; ++k){
                    matrix[k][i] = 0;
                }
            }
        }
        for(int i = 1; i < h; ++i){
            //clear row i to zero
            if(matrix[i][0] == 0){
                for(int k = 0; k < w; ++k){
                    matrix[i][k] = 0;
                }
            }
        }
        if(firstRowZero){
            for(int i = 0; i < w; ++i){
                matrix[0][i] = 0;
            }
        }
        if(firstColumnZero){
            for(int i = 0; i < h; ++i){
                matrix[i][0] = 0;
            }
        }
    }
};

思路就是:
由于每一行or列是否被清零只与该行or列的元素有关而与别的元素无关
1. 预处理,看第一行是否有0元素,第一列是否有零元素(并用两个bool变量标记)
2. 把matrix[i][j] (i != 1 && j != 1)的为0的信息存在第一行或者第一列对应的位置
3. 用记录在第一行和第一列里的信息更新除第一行和第一列以外的元素
4. 根据两个bool变量更新第一行和第一列的元素

一开始写出了bug,就是代码最后两个if判断之前,修改了第一行和第一列用于标记状态的元素,从而使得只要matrix[0][0]为0,那么接着column 0被清零,然后每个row就都被清零了=。-
(总结起来就是对矩阵的清零操作影响了用于标记的行和列,接着使得这个清零因为矩阵的修改而传递(这是与题意相违背的))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值