[C++]LeetCode: 49 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?

Anwser 1: 利用额外O(m + n)空间

思路:建立行和列的含0标记,然后根据标记将相应的元素置0;

复杂度:O(mn)

Attention: 由于无法直接将matrix某列直接置0,注意置某行置某列的方法。

AC Code:

<span style="font-size:14px;">class Solution {
public:
    void setZeroes(vector<vector<int> > &matrix) {
        //额外空间O(m+n) 即标记m行和n列是否有含0的元素
        
        int row = matrix.size();
        if(row < 1) return;
        int col = matrix[0].size();
        //标记行和列是否含0元素
        vector<bool> rowRecoder(row);
        vector<bool> colRecoder(col);
        
        //初始化行列的标记
        for(int i = 0; i < row; i++)
        {
            for(int j = 0; j < col; j++)
            {
                if(matrix[i][j] == 0)
                {
                    rowRecoder[i] = true;
                    colRecoder[j] = true;
                }
            }
        }
        
        for(int i = 0; i < row; i++)
        {
            for(int j = 0; j < col; j++)
            {
                if(rowRecoder[i]) matrix[i][j] = 0;
                else if(colRecoder[j]) matrix[i][j] = 0;
            }
        }
     }
};</span>

Anwser 2: 使用常数空间

常数空间的话,第一可以考虑是不是固定数量的几个变量能搞定;否则可以考虑是不是问题本身已经提供了足够的空间。

思路:

这道题属于后者,就是利用矩阵的第一行和第一列来作为辅助空间使用。不用开辟新的存储空间。方法就是:
1.先确定第一行和第一列是否需要清零
即,看看第一行中是否有0,记下来。也同时记下来第一列中有没有0。
2.扫描剩下的矩阵元素,如果遇到了0,就将对应的第一行和第一列上的元素赋值为0
这里不用担心会将本来第一行或第一列的1改成了0,因为这些值最后注定要成为0的(确定A[i][j]为0,则A[0][j]和A[i][0]为0)。
3.根据第一行和第一列的信息,已经可以将剩下的矩阵元素赋值为结果所需的值了
即,拿第一行为例,如果扫描到一个0,就将这一列都清0.
4.根据1中确定的状态,处理第一行和第一列。
如果最开始得到的第一行中有0的话,就整行清零。同理对列进行处理。

Attention: 

1.注意第二步和第三步,尤其是第三步的赋值操作,判断到无论是第i行中有0,或者第j列含0,都可以将A[i][j]置0(根据题目规则)。

if(matrix[0][ci] == 0 || matrix[ri][0] == 0)
                {
                    matrix[ri][ci] = 0;
                }

2.判断到第1行或者第一列中含有0值,即可以break 无须继续判断。

复杂度:O(mn)

AC Code:

<span style="font-size:14px;">class Solution {
public:
    void setZeroes(vector<vector<int> > &matrix) {
        int row = matrix.size();
        int col = matrix[0].size();
        if(row < 1 || col < 1) return;
        
        bool firstRowhasZero = false;
        bool firstColhasZero = false;
        //using first row and col as storage
        
        //1.search zero in first row and col to determin it's own status
        for(int ci = 0; ci < col; ci++)
        {
            if(matrix[0][ci] == 0)
            {
                firstRowhasZero = true;
                break;
            }
        }
        
        for(int ri = 0; ri < row; ri++)
        {
            if(matrix[ri][0] == 0)
            {
                firstColhasZero = true;
                break;
            }
        }
        
        //2.search zeros in other position to sign the first row and col 搜索除第一行和第一列外的其他元素
        for(int ri = 1; ri < row; ri++)
        {
            for(int ci = 1; ci < col; ci++)
            {
                if(matrix[ri][ci] == 0)
                {
                    matrix[ri][0] = 0;
                    matrix[0][ci] = 0;
                }
            }
        }
        
        //3.set zeroes in other positions according to first col and row
        for(int ri = 1; ri < row; ri++)
        {
            for(int ci = 1; ci < col; ci++)
            {
                if(matrix[0][ci] == 0 || matrix[ri][0] == 0)
                {
                    matrix[ri][ci] = 0;
                }
            }
        }
        
        //4.set zeroes for first row and col
        if(firstRowhasZero)  
        {
            for(int ci = 0; ci < col; ci++)
            {
                matrix[0][ci] = 0;
            }
        }
        
        if(firstColhasZero)  
        {
            for(int ri = 0; ri < row; ri++)
            {
                matrix[ri][0] = 0;
            }
        }
        
        return;
    }
    
};</span>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值