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.

click to show follow up.

Follow up: 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?

新建矩阵法

复杂度

时间 O(NM) 空间 O(NM)

思路

最简单的方法就是建一个同样大小的矩阵,在原矩阵中遇到一个0,就将新矩阵的行和列设为0

首行首列暂存法

复杂度

时间 O(NM) 空间 O(1)

思路

实际上,我们只需要直到哪些行,哪些列需要被置0就行了,最简单的方法就是建两个大小分别为M和N的数组,来记录哪些行哪些列应该被置0。那有没有可能不用额外空间呢?我们其实可以借用原矩阵的首行和首列来存储这个信息。这个方法的缺点在于,如果我们直接将0存入首行或首列来表示相应行和列要置0的话,我们很难判断首行或者首列自己是不是该置0。这里我们用两个boolean变量记录下首行和首列原本有没有0,然后在其他位置置完0后,再单独根据boolean变量来处理首行和首列,就避免了干扰的问题。

代码

public class Solution {
    public void setZeroes(int[][] matrix) {
        if(matrix.length == 0) return;
        boolean firstRowZero = false, firstColZero = false;
        // 记录哪些行哪些列需要置0,并判断首行首列是否需要置0
        for(int i = 0; i < matrix.length; i++){
            for(int j = 0; j < matrix[0].length; j++){
                if(i != 0 && j != 0 && matrix[i][j] == 0){
                    matrix[i][0] = 0;
                    matrix[0][j] = 0;
                } else if (matrix[i][j] == 0){
                    // 如果首行或首列出现0,则标记其需要置0,否则沿用上次值
                    firstRowZero = i == 0 ? true : firstRowZero;
                    firstColZero = j == 0 ? true : firstColZero;
                }
            }
        }
        // 将除首行首列的位置置0
        for(int i = 1; i < matrix.length; i++){
            for(int j = 1; j < matrix[0].length; j++){
                if(matrix[0][j] == 0 || matrix[i][0] == 0){
                    matrix[i][j] = 0;
                }
            }
        }
        // 如果必要,将首列置0
        for(int i = 0; firstColZero && i < matrix.length; i++){
            matrix[i][0] = 0;
        }
        // 如果必要,将首行置0
        for(int j = 0; firstRowZero && j < matrix[0].length; j++){
            matrix[0][j] = 0;
        }
    }
}

ethannnli
858 声望360 粉丝