题目
编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。
示例 1:
输入:
[
[1,1,1],
[1,0,1],
[1,1,1]
]
输出:
[
[1,0,1],
[0,0,0],
[1,0,1]
]
题解1 记录行列
思路
首先想到的是使用额外空间进行存储。
先遍历矩阵并使用集合记录存在0元素的行号和列号,然后遍历行号和列号进行赋0。
时间复杂度为O(m*n)O(m∗n)空间复杂度为O(m+n)O(m+n)。
代码
class Solution:
def setZeroes(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
li = []
lj = []
m = len(matrix)
n = len(matrix[0])
for i in range(m):
for j in range(n):
if matrix[i][j] == 0:
li.append(i)
lj.append(j)
li = list(set(li))
lj = list(set(lj))
for i in li:
for j in range(n):
matrix[i][j] = 0
for i in range(m):
for j in lj:
matrix[i][j] = 0
复习知识点
知识点1.list列表去重
方法一:使用set()进行去重,去重后需再次转为list
arr = [1,2,2,4,4,5]
arr = list(set(arr)) # [1,2,4,5]
题解2 原地标记
思路
除了使用额外的数组,我们可以直接用矩阵的第一行和第一列来标记。
由于第一行、第一列用来做标记,它们的值可能会因为标记而发生改变,因此,需要额外的变量 i0, j0 来标记第一行、第一列是否需要被清零。
代码
class Solution:
def setZeroes(self, matrix: List[List[int]]) -> None:
m, n = len(matrix), len(matrix[0])
# 第一行是否包含 0
i0 = any(v == 0 for v in matrix[0])
# 第一列是否包含 0
j0 = any(matrix[i][0] == 0 for i in range(m))
for i in range(1, m):
for j in range(1, n):
if matrix[i][j] == 0:
# 用第一行、第一列标记
matrix[i][0] = matrix[0][j] = 0
for i in range(1, m):
for j in range(1, n):
if matrix[i][0] == 0 or matrix[0][j] == 0:
matrix[i][j] = 0
if i0:
for j in range(n):
matrix[0][j] = 0
if j0:
for i in range(m):
matrix[i][0] = 0
复习知识点
知识点2.any函数
Python内置的any函数用来判断一个可迭代对象中是否至少有一个值为True,如果是则返回True,否则返回False。相当于对可迭代对象的所有元素做or运算,但是返回的结果只有True或False.
print(any([1, 2, 3])) # True
print(any(['', 0, False])) # False
print(any(['', 1, False])) # True
和any()类似的是all(),all()是判断可迭代对象中每一个元素是否都是True,是则返回True,否则返回False。也就是说只要有一个是False则返回False。
print(any([1, 2, 3])) # True
print(any(['', 0, False])) # False
print(any(['', 1, False])) # False
注意
any()和all()对于空的迭代对象的返回结果是不一样的
print(any([])) # False
print(all([])) # True
可以理解为:
any是”至少有一个值为True时返回True”,空列表显然不满足,所以是False。
all是“至少有一个值为False时返回False”,空列表显然不满足,所以是True。