73:矩阵置零

问题描述

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

示例

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

题目分析

汗,这题我一开始把原地算法想成了是原地修改。然后想当然的用了2个set记录要变0的行和列,然后让他们变0.
其实人家说的原地算法是利用O(1)的空间复杂度。
我们在思考过程中发现,如果你想用扩展的方式来搞定的话,要解决以下问题:

  • 扩展了行和列之后,你在下次遍历的时候就不清楚这个位置到底是原本就是0,还是被你修改过后是0了。

诚然,对于Python这种语言,你完全可以将初始值为0的值置为False,这样的话我们只需要判断是不是False就可以了。但是对于Java等类型严格的语言来说这题就不可解了吗?不是的。
我们发现这题就是个映射的思想。我们发现某个元素matrix[i][j]为0时,那代表了我们需要把matrix[i][…],和matrix[…][j] 全部置为0.所以我们可以把这个为0的特征映射到matrix[i][0] 和matrix[0][j]上。这样的话我们就可以根据第一行第一列的状态进行初始化了。
我们利用第一行第一列的状态时,我们并不能同时对第一行或者第一列进行置0操作。因为那样的话就违背了我们的初衷:我们没有解决上面提到的问题。所以我们可以对除第一行第一列之外的元素进行置0操作,弄完了之后再说第一行第一列的事儿。
第一行第一列比较特殊的。因为我们是把其他元素的特征存储在了第一行,所以我们要在存储之前搞明白到底要怎么对第一行第一列进行操作。
我们需要两个flag标记一下到底在第一行/第一列有没有遇到0,以便最后进行处理。

AC代码:

class Solution:
    def setZeroes(self, matrix) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        if len(matrix) == 0:
            return
        flagI = flagJ = False
        for j in range(len(matrix[0])):
            if matrix[0][j] == 0:
                flagJ = True
        for i in range(len(matrix)):
            if matrix[i][0] == 0:
                flagI = True
            for j in range(len(matrix[0])):
                if matrix[i][j] == 0:
                    matrix[i][0] = matrix[0][j] = 0
        for i in range(1,len(matrix)):
            for j in range(1,len(matrix[0])):
                if matrix[i][0] == 0 or matrix[0][j] == 0:
                    matrix[i][j] = 0
        if flagI:
            for i in range(len(matrix)):
                matrix[i][0] = 0
        if flagJ:
            for j in range(len(matrix[0])):
                matrix[0][j] = 0
        print(matrix)
s = Solution()
s.setZeroes([[0,1,2,0],[3,4,5,2],[1,3,1,5]])
发布了333 篇原创文章 · 获赞 22 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_41687289/article/details/103652687