LintCode 162: Set Matrix Zeroes

  1. Set Matrix Zeroes

Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place.

Example
Example 1:

Input:[[1,2],[0,3]]
Output:[[0,2],[0,0]]
Example 2:

Input:[[1,2,3],[4,0,6],[7,8,9]]
Output:[[1,0,3],[0,0,0],[7,0,9]]
Challenge
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?

解法1:用set。
代码如下:

class Solution {
public:
    /**
     * @param matrix: A lsit of lists of integers
     * @return: nothing
     */
    void setZeroes(vector<vector<int>> &matrix) {
        int m = matrix.size();
        if (m == 0) return;
        int n = matrix[0].size();
        if (n == 0) return;
        
        unordered_set<int> zeroRows;
        unordered_set<int> zeroCols;
        
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (matrix[i][j] == 0) {
                    zeroRows.insert(i);
                    zeroCols.insert(j);
                }        
            }
        }
        
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (zeroRows.find(i) != zeroRows.end() || zeroCols.find(j) != zeroCols.end()) {
                    matrix[i][j] = 0;
                }
            }
        }
        
        return;
    }
};

解法2:不用额外空间的解法。
参考了网上的解法。思路比较奇妙,就是把每行或每列的有无0的信息放在行头或列头。
注意:

  1. 假设仅仅做下面两个循环:
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (matrix[i][j] == 0) {
                    matrix[i][0] = 0;
                    matrix[0][j] = 0;
                }
            }
        }
        
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                matrix[i][j] = (matrix[i][0] == 0 || matrix[0][j] == 0) ? 0 : matrix[i][j];
            }
        }

以下面input为例:
[[-4,-2147483648,6,-7,0],[-8,6,-8,-6,0],[2147483647,2,-9,-6,-10]]
如果不单独处理row0hasZero和col0hasZero,在处理第0行 (和第1行) 的时候就会把matrix[0][0] (和matrix[1][0]) 置零。第2个forfor循环处理到matrix[2][0]时发现matrix[0][0]=0,就会把matrix[2][0]设为0。但这是不对的,事实上第0列根本没有0元素。
原因是第0行和第0列本身还要承担该行或该列是否有0的信息,该信息不应该和其它行列含0信息混淆。

代码如下:

class Solution {
public:
    /**
     * @param matrix: A lsit of lists of integers
     * @return: nothing
     */
    void setZeroes(vector<vector<int>> &matrix) {
        int m = matrix.size();
        if (m == 0) return;
        int n = matrix[0].size();
        if (n == 0) return;
        
        bool row0hasZero = false, col0hasZero = false;
        
        for (int i = 0; i < n; ++i) {
            if (matrix[0][i] == 0) row0hasZero = true;
        }
        
        for (int i = 0; i < m; ++i) {
            if (matrix[i][0] == 0) col0hasZero = true;
        }
        
        for (int i = 1; i < m; ++i) {
            for (int j = 1; j < n; ++j) {
                if (matrix[i][j] == 0) {
                    matrix[i][0] = 0;
                    matrix[0][j] = 0;
                }
            }
        }
        
        for (int i = 1; i < m; ++i) {
            for (int j = 1; j < n; ++j) {
                matrix[i][j] = (matrix[i][0] == 0 || matrix[0][j] == 0) ? 0 : matrix[i][j];
            }
        }

        for (int i = 0; i < m; ++i) {
            matrix[i][0] = col0hasZero ? 0 : matrix[i][0];
        }        
        
        for (int i = 0; i < n; ++i) {
            matrix[0][i] = row0hasZero ? 0 : matrix[0][i];
        }
        return;
    }
};

代码同步在:
https://github.com/luqian2017/Algorithm

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值