zoukankan      html  css  js  c++  java
  • [LeetCode]23. 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?

     
    解法1:新建一个同样大小数组,先扫描行,若某行存在零元素,则整行清零;再扫描列,若某列存在零元素,则整列清零。最后将其赋给原矩阵。空间复杂度O(mn)。
    class Solution {
    public:
        void setZeroes(vector<vector<int>>& matrix) {
            if (matrix.empty() || matrix[0].empty())
                return;
            int m = matrix.size();
            int n = matrix[0].size();
    
            vector< vector<int> > tmpMat;
            for (int i = 0; i < m; i++)
            {
                tmpMat.push_back(matrix[i]);
                if (find(matrix[i].begin(), matrix[i].end(), 0) != matrix[i].end())
                    tmpMat[i].assign(n, 0);
            }
            for (int j = 0; j < n; j++)
            {
                for (int i = 0; i < m; i++)
                {
                    if (matrix[i][j] == 0)
                    {
                        for (int k = 0; k < m; k++)
                            tmpMat[k][j] = 0;
                        break;
                    }
                }
            }
            for (int i = 0; i < m; i++)
                copy(tmpMat[i].begin(), tmpMat[i].end(), matrix[i].begin());
        }
    };
    解法2:新建一个数组,用来存储矩阵中所有零元素的位置。然后再扫描一遍矩阵,将零元素所在的行列清零即可。空间复杂度O(m+n)。
    class Solution {
    public:
        void setZeroes(vector<vector<int>>& matrix) {
            if (matrix.empty() || matrix[0].empty())
                return;
            int m = matrix.size();
            int n = matrix[0].size();
    
            vector< pair<int, int> > zeroIndex;
            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    if (matrix[i][j] == 0)
                        zeroIndex.push_back(make_pair(i, j));
                }
            }
            for (int i = 0; i < zeroIndex.size(); i++)
            {
                for (int j = 0; j < n; j++)
                    matrix[zeroIndex[i].first][j] = 0;
                for (int k = 0; k < m; k++)
                    matrix[k][zeroIndex[i].second] = 0;
            }
        }
    };

    解法3:解法2中zeroIndex所用空间可以用原矩阵中某个零元素所在的行和列来代替,这样可以使得空间复杂度下降为O(1)。不需要将所有零元素的位置存下来。对于两个零元素坐标(i,j)和(k,l),如果i!=k&&k!=l,则需要将两者均存储下来,否则如果有i=k(或者j=l),则这两个零元素对矩阵行(或者列)的清零效果是一样的,只需要存储其中的一个(i或者k)(或者 j或者l)即可,而j和l(或者i和k)则必须分开存储。步骤:

    - 先扫描第一行第一列,如果有0,则将各自的flag设置为true
    - 然后扫描除去第一行第一列的整个数组,如果有0,则将对应的第一行和第一列的数字赋0
    - 再次遍历除去第一行第一列的整个数组,如果对应的第一行和第一列的数字有一个为0,则将当前值赋0
    - 最后根据第一行第一列的flag来更新第一行第一列

    class Solution {
    public:
        void setZeroes(vector<vector<int>>& matrix) {
            if (matrix.empty() || matrix[0].empty())
                return;
            int m = matrix.size();
            int n = matrix[0].size();
    
            bool rh0 = false, ch0 = false; //标识第一行和第一列是否存在0
            for (int i = 0; i < n && !rh0; i++)
                rh0 = matrix[0][i] == 0 ? true : rh0;
            for (int i = 0; i < m && !ch0; i++)
                ch0 = matrix[i][0] == 0 ? true : ch0;
            for (int i = 1; i < m; i++) //对除去原矩阵的第一行和第一列得到的新矩阵扫描,标记0的位置
            {
                for (int j = 1; j < n; j++)
                {
                    if (matrix[i][j] == 0)
                    {
                        matrix[i][0] = 0;
                        matrix[0][j] = 0;
                    }
                }
            }
            for (int i = 1; i < m; i++) //对除去原矩阵的第一行和第一列得到的新矩阵进行清零操作
            {
                for (int j = 1; j < n; j++)
                {
                    if (matrix[i][0] == 0 || matrix[0][j] == 0)
                        matrix[i][j] = 0;
                }
            }
            //对第一行第一列进行清零操作
            if (rh0)
                matrix[0].assign(n, 0);
            if (ch0)
            {
                for (int i = 0; i < m; i++)
                    matrix[i][0] = 0;
            }
        }
    };
  • 相关阅读:
    年轻人如何去有效的学习(很好的鸡汤,一语惊醒梦中人)
    python基础07 函数
    python基础06 循环
    python基础05 缩进与选择
    python基础04 运算
    python基础03 序列
    python基础02 基本数据类型
    python基础01 Hello World
    CSS3(三)BFC、定位、浮动、7种垂直居中方法
    CSS3(二)Box Model、边距折叠、内联与块标签、CSSReset
  • 原文地址:https://www.cnblogs.com/aprilcheny/p/4874831.html
Copyright © 2011-2022 走看看