Set Matrix Zeros

本文介绍了一种高效的矩阵置零算法,通过利用O(1)额外空间而非传统的O(n+m)空间复杂度来标记需要置零的行列。文章详细解释了如何避免在更新过程中覆盖必要的标记信息,并特别关注于处理第一行和第一列的特殊情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int rowSize = matrix.size();
        int colSize = matrix[0].size();
        int col = 1;
        for (int i = 0; i < rowSize; i++)
        {
            if (matrix[i][0] == 0) 
                col = 0;
            for (int j = 1; j < colSize; j++)
            {
                if (matrix[i][j] == 0)
                {
                    matrix[i][0] = 0;
                    matrix[0][j] = 0;
                }    
            }
        }
        // TODO here is >= not >
        for (int i = rowSize - 1; i >= 0 ; i--)
        {
            // TODO here is j >= 1!!!
            for(int j = colSize - 1; j >= 1; j--)
            {
                if ((matrix[i][0] == 0) || (matrix[0][j] == 0))
                {
                    matrix[i][j] = 0;
                }
            }
            
            // TODO here the code is outside of the j loop but inside of i loop
            if (col == 0)
            {
                matrix[i][0] = 0;
            }
        }
            
    }

};




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;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值