LeetCode 73:Set Matrix Zeros

题目:给定一个m*n的数组,如果数组里的某个元素为0,那么把这个元素的整行和整列元素都设为0。要求空间复杂度越低越好。

解1:

直接再开辟一个同样大小的数组进行判断操作,优点是时间复杂度低,缺点是空间复杂度太大,为O(mn)

解2:

开辟两个一维数组,大小分别为m和n,且称为A和B。如果i行有元素为0,则设A[i]为0,如果j列有元素为0,则设B[j]为0。这样再循环遍历完所有元素之后,即可通过A和B的信息给出matrix的0的信息了。这相比解法1,空间复杂度降了不少,但其实还有更好的算法(更低的空间复杂度)。

解3:

原题提示了最优的算法可以达到constant space,而如果要求是constant sapce,我们应该首先从以下两个方面来考虑这个问题:1.通过固定数目的几个变量搞定;2.在原来数据基础上进行优化。第2个的意思就是说用原来数据空间来存储所需的信息。所以解法3是把解2中的那个A和B用matrix里的一行一列来代替了,达到空间复杂度为O(1)的效果。下面贴出代码:

class Solution {
public:
    void setZeroes(vector<vector<int> > &matrix) {
        const int ROW = matrix.size();
        if (ROW == 0)
            return;
        const int COL = matrix[0].size();
        if (COL == 0)
            return;
        
        // we store the 0 information in
        // the 1st row and 1st col
        bool R00 = false;
        for(int i = 0; i < COL; ++i)
            if (matrix[0][i] == 0)
            {
                R00 = true;
                break;
            }
        bool C00 = false;
        for(int i = 0; i < ROW; ++i)
            if (matrix[i][0] == 0)
            {
                C00 = true;
                break;
            }
        
        // now traverse the remaining parts of
        // the matrix and store 0 into the 
        // first row
        for(int i = 1; i < ROW; ++i)
            for(int j = 1; j < COL; ++j)
                if (matrix[i][j] == 0)
                {
                    matrix[i][0] = 0;
                    matrix[0][j] = 0;
                }
                
        // use the first row/col information to
        // fill zeros
        for(int i = 1; i < ROW; ++i)
            if (matrix[i][0] == 0)
                for(int j = 1; j < COL; ++j)
                    matrix[i][j] = 0;
        
        for(int i = 1; i < COL; ++i)
            if (matrix[0][i] == 0)
                for(int j = 1; j < ROW; ++j)
                    matrix[j][i] = 0;
        
        // Finally check the 1st row/col
        if (R00)
            fill(begin(matrix[0]), end(matrix[0]), 0);
        if (C00)
            for(int i = 0; i < ROW; ++i)
                matrix[i][0] = 0;
        
        return;
    }
};
但是其实本题还有更为简单的算法,这也是我在leetcode上提交的算法。

解法4:

使用trick number,这个名词是我起的,也意味着这个算法本身也比较的trick。思想是取一个matrix里不太会用到的一个数,比如题目里是整型,那么我们就起-12345678,就类似这种不可能在matrix里出现的数,然后将0元素的整列和整行都设为这个数,这样在一轮下来之后,再重新遍历matrix,如果元素是-12345678,那么救把元素设为0,这个算法的时间复杂度为O(mn),控件复杂度为O(1)。leetcode有人评论说这种算法不行,因为没考虑所有的情况,但是我认为,现实生活遇到的问题都是特定条件下的,就比如说如果这个matrix是一个位置坐标的信息,里面的所有元素都是>=0的元素,那么完全可以采取-1作为trick number;又比如说如果matrix是存储尺度很小的数据时,那么我完全可以采用一个很大的数,比如99999999作为trick number。所以这种算法是可取的,但是要视具体情况来定。不管怎样,反正取-100000作为trick number也AC了这题。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值