Using O(n+m) and O(1) space to solve this problem, both accepted with 44ms in C, well-explained


  • 1

    The first solution is quite intuitive, using two arrays to record the status of each row and column since once a cell is zero the whole row and the whole column should be set to zero - quite enough to record the information we need to set the matrix.


    //AC - 44ms;
    void setZeroes(int** matrix, int rSize, int cSize)
    {
        bool *rSet = (bool*)malloc(sizeof(bool)*rSize);
        bool *cSet = (bool*)malloc(sizeof(bool)*cSize);
        memset(rSet, 0, sizeof(bool)*rSize);
        memset(cSet, 0, sizeof(bool)*cSize);
        for(int r = 0; r < rSize; r++)
            for(int c = 0; c < cSize; c++)
                if(!matrix[r][c])
                {
                    rSet[r] = true;
                    cSet[c] = true;
                }
        for(int r = 0; r < rSize; r++)
            if(rSet[r])
                memset(matrix[r], 0, sizeof(int)*cSize);
        for(int c = 0; c < cSize; c++)
            if(cSet[c])
                for(int r = 0; r < rSize; r++)
                    matrix[r][c] = 0;
    }
    

    Compared to the first O(n+m) solution, we are going to just use O(1) space to hack this problem. As we should know in the first solution, we can just store the state in the first row and first column in traversal and then use those stored states to set the matrix. But there are two problems we need to solve first:

    • when we trying to use the stored states to set the matrix from the top-left to bottom-right, the stored states will be updated and over-written, so first we should traverse the matrix from the bottom-right to the top-left to prevent this from happening;
    • after avoiding over-written case, we should also be aware that the first column and the first row is a sensitive area; an example should be taken here: suppose there is a matrix[[1,1, 0],[1,2,1]], the first row will make the first column cells all zeroes (the third cell of first row will set matrix[0][0] to zero and since we are traversing from bottom-left to top-right and referring the first row and first column to set the value of the cells) but this is not the case actually. So we need to take actions to prevent the first row affecting the first column; how about the first row, does the first column will affect the first row? Since we are now traversing from bottom-right to top-left and the first column is taken away for special treatment, that case will not then happen; so the problem is becoming this: the first column should be treated as a special and then from the initialisation to the setting part, the first column is taken away.

    //AC - 44ms;
    void setZeroes(int** matrix, int rSize, int cSize)
    {
        int col0 = 1; //the first column can be affected by the other columes of the first row;
        for(int r = 0; r < rSize; r++)
        {
            if(matrix[r][0]==0) col0 = 0;
            for(int c = 1;  c < cSize; c++)
                if(matrix[r][c]==0)
                    matrix[r][0] = matrix[0][c] = 0;
        }
        for(int r = rSize-1; r > -1; r--) //using reverse direction to ensure previously set value will not affect the latter ones;
        {
            for(int c = cSize-1; c > 0; c--)
                if(matrix[r][0]==0 || matrix[0][c]==0)
                    matrix[r][c] = 0;
            if(col0==0) matrix[r][0] = 0; //ensure the first column will not affect the other columns in the same row;
        }
    }

Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.