Leetcode 073 矩阵置零 Python C++ 史上最详细题解系列

题目:

给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法

示例 1:

输入: 
[
  [1,1,1],
  [1,0,1],
  [1,1,1]
]
输出: 
[
  [1,0,1],
  [0,0,0],
  [1,0,1]
]

示例 2:

输入: 
[
  [0,1,2,0],
  [3,4,5,2],
  [1,3,1,5]
]
输出: 
[
  [0,0,0,0],
  [0,4,5,0],
  [0,3,1,0]
]

进阶:

  • 一个直接的解决方案是使用  O(mn) 的额外空间,但这并不是一个好的解决方案。
  • 一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。
  • 你能想出一个常数空间的解决方案吗?


每天更新一道python or C++ leetcode题,力求讲解清晰准确,客官们可以点赞或者关注。

进阶O(m*n) 方法:重新构建一个m*n的数组,先把0填进去,然后把0所在的行和列填为0,然后把剩下的数填入相对应的位置上。

进阶O(m+n)方法:两个数组,bool1[m] 和 bool2[n] 分别存某行有零,后者某列有零。之后根据数组值将原矩阵相应位置置零。额外空间O(m + n)。比如bool1[0]为true代表0行有0,bool2[3]为true代表index为3的列有0;

代码:(仅c++)

class Solution {
public:
    void setZeroes(vector<vector<int> > &matrix) {
        int len1 = matrix.size();
        if (len1 == 0) return ;
        int len2 = matrix[0].size();
        if (len2 == 0) return ;
        vector<bool > row(len1), col(len2);
        for (int i = 0; i < len1; i++)
            for (int j = 0; j < len2; j++)
            {
                if (matrix[i][j] == 0)
                {
                    row[i] = true; col[j] = true;   
                }
            }
        for (int i = 0; i < len1; i++)
            for (int j = 0; j < len2; j++)
            {
                if (row[i] == true)
                    matrix[i][j] = 0;
                else if (col[j] == true)
                    matrix[i][j] = 0;
            }
        return ;
    }
};

方法三(常量空间):

先扫描数组记下0,0的位置(行和列),然后再次扫描数组,检索每个元素,当所在行数与其中任意一个0的行数相同时便置为0,当所在行数与其中任意一个0的列数相同时便置为0。

Python:

class Solution:
    def setZeroes(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: void Do not return anything, modify matrix in-place instead.
        """
        pos_list = []
        col = len(matrix[0])
        row = len(matrix)
        for i in range(row):
            for j in range(col):
                if matrix[i][j] == 0:
                    #记下0的位置
                    pos_list.append([i, j])

        for cor in pos_list:#遍历所有的0坐标
            temrow = cor[0]#横坐标
            temcol = cor[1]#纵坐标
            #把行和列置为0
            for i in range(row):
                matrix[i][temcol] = 0
            for j in range(col):
                matrix[temrow][j] = 0
        

C++(如果你认为上面那种不是常量空间,接下来的这种解法保证了常数空间,因为我们只记录最靠近右下角的0的位置.)

class Solution {
public:
    void setZeroes(vector<vector<int> > &matrix) {
        int len1 = matrix.size();
        if (len1 == 0) return ;
        int len2 = matrix[0].size();
        if (len2 == 0) return ;
        int row = -1, col = -1;
        for (int i = 0; i < len1; i++)
            for (int j = 0; j < len2; j++)
            {
                if (matrix[i][j] == 0)
                {
                    row = i; col = j;//记录的是最靠近右下角的0的位置
                }
            }
        if (row == -1) return;
        for (int i = 0; i < len1; i++)
            for (int j = 0; j < len2; j++)
            {
                if (matrix[i][j] == 0 && i != row && j != col)//如果有0项,但不是我们最后记录的那一个
                {
                    matrix[i][col] = 0;
                    matrix[row][j] = 0;
                }
            }
        for (int i = 0; i < len1; i++)
            for (int j = 0; j < len2; j++)
            {
                if (i != row && j != col)
                {
                    if (matrix[i][col] == 0 )
                        matrix[i][j] = 0;
                    else if (matrix[row][j] == 0)
                        matrix[i][j] = 0;
                }
            }
        int index = -1; 
        while(++index < len1) matrix[index][col] = 0;
        index = -1;
        while(++index < len2) matrix[row][index] = 0;
        return ;
    }
};

C++的解法比较曲折,感兴趣的朋友可以自己尝试追踪一下轨迹理解一下代码,(这种解法是绝对符合题意的)

猜你喜欢

转载自blog.csdn.net/weixin_41958153/article/details/81568947