• [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;
            }
        }
    };
  • 相关阅读:
    tensorflow 2.0 学习 (十) 拟合与过拟合问题
    tensorflow 2.0 学习 (九) tensorboard可视化功能认识
    tensorflow 2.0 学习 (八) keras模块的认识
    tensorflow 2.0 学习 (七) 反向传播代码逐步实现
    tensorflow 2.0 学习 (六) Himmelblua函数求极值
    tensorflow 2.0 学习 (五)MPG全连接网络训练与测试
    arp协议简单介绍
    Pthread spinlock自旋锁
    线程和进程状态
    内核态(内核空间)和用户态(用户空间)的区别和联系·
  • 原文地址:https://www.cnblogs.com/aprilcheny/p/4874831.html
Copyright © 2020-2023  润新知