LC73. 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.

O(mn) sol

We can use a list to hold all the positions that have 0 in it. Because there could be O(mn) 0 in the list, this solution will take O(mn) space

O(m + n) space

Because there are only m + n rows and columns, we can just record the rows and columns that need to be emptied.

def setZeroes(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        This is very similar to a previous problem
        I think it is find the smallest number that's out of line
        O(mn): create a list to hold position of 0 entry
        """
        zeros_r = {}
        zeros_c = {}
        for i in range(len(matrix)):
            for j in range(len(matrix[0])):
                if matrix[i][j] == 0:
                    zeros_r[i] = i
                    zeros_c[j] = j
        for key in zeros_r:
            for i in range(len(matrix[0])):
                matrix[key][i] = 0
        for col in zeros_c:
            for i in range(len(matrix)):
                matrix[i][col] = 0

Constant space

The need to memorize what columns and rows we need to delete

We can not just delete the column and row when we see a zero. So the need to store them are HARD.

Use first row and first column to store if a row and column needs to be zeroed.

If matrix[i][j] == 0, then matrix[0][j] = 0 and matrix[i][0] = 0. We later need to zero every entry with [?][j] and entry with [i][?].

In the first row, if an entry matrix[0][j] is 0, that means every entry in column j will be zero.
In the first column, matrix[i][0], if matrix[i][0] = 0 then every entry in row i will be 0

Need to use a variable to record what happened with first column

Based on the rule above, matrix[0][0] will be 0 if either first column or first row becomes 0. We can use another variable to hold whether first col is zero and use matrix[0][0] to record information abot the first row.

CAUTION!!! Since we are checking first col separately, we need to check the for loop as well.

zero from bottom right to top left

Since we use first row and first column to store information, we want to zero them out LAST. So we start from the bottom right.

public:void setZeroes(vector<vector<int> > &matrix) {
    int col0 = 1, rows = matrix.size(), cols = matrix[0].size();
    for(int i = 0; i < rows; i ++){
        if (matrix[i][0] == 0) col0 = 0; 
        for( int j = 1; j < cols; j ++){
            if (matrix[i][j] == 0)
                matrix[i][0] = matrix[0][j] = 0;
        }
    }

    for(int i = rows - 1; i >= 0; i --){
        for(int j = cols - 1; j >= 1; j --){
            if (matrix[i][0] == 0 or matrix[0][j] ==0){
                matrix[i][j] = 0;
            }   
        }
        if (col0 == 0) matrix[i][0] = 0;
    }
}

Bugs

Starting column at 1

Because we take care of the first column outside of the nested for loop, if we start column scan at 0, and see an entry in the first column to be 0, then we will set matrix[0][0] to zero, but matrix[0][0] stores whether the first row should be cleared. It will leads to error.

EG

1 1 1 
0 1 1 
1 1 1

If we scan from the column 0, then it will flip matrix[0][0] to 0 and when we reconstruct the new matrix we will get

0 0 0 
0 0 0 
0 1 1

Leave a Reply

Your email address will not be published. Required fields are marked *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax