LeetCode 73:Set Matrix Zeros

来源:互联网 发布:程序员出差多吗 编辑:程序博客网 时间:2024/06/06 01:47

题目:给定一个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了这题。


0 0
原创粉丝点击