目录
矩阵置零
给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地(http://baike.baidu.com/item/%E5%8E%9F%E5%9C%B0%E7%AE%97%E6%B3%95) 算法。
什么是原地算法(摘自百度百科)
在计算机科学中,一个原地算法(in-place algorithm)是一种使用小的,固定数量的额外空间来转换资料的算法。当算法执行时,输入的资料通常会被要输出的部分覆盖掉,即生成数据的过程中会部分覆盖原始数据。
一个算法有时候会不正当地被称为原地算法,只因为它用它的输出资料会覆盖掉它的输入资料。事实上这并不足够(在快速排序案例中所展示的)或是它所必须的;输出资料的空间可能是固定的,或如果以输出为串流资料而言,也甚至是可能无法被数清楚的。另一方面来看,有时候要决定一个算法是不是原地,而数它的输出空间可能是比较可行的,像是底下的第一个的 reverse 范例;如此使得它更难去严格地定义原地算法。在理论上的应用像是log-space reduction,更是典型的总是忽略输出的空间。
体现在本题中,主要是对于0值存在的行列进行置0处理,即则将其所在行和列的所有元素都设为 0 。
#以行为例,将存在0值的行全部置0,这里对部分原始数据进行了覆盖
for i in r:
for j in range(n):
matrix[i][j] = 0
进阶:
- 一个直观的解决方案是使用 O(mn) 的额外空间,但这并不是一个好的解决方案。
- 一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。
- 你能想出一个仅使用常量空间的解决方案吗?
示例 1:
输入:matrix = [[1,1,1],[1,0,1],[1,1,1]]
输出:[[1,0,1],[0,0,0],[1,0,1]]
示例 2:
输入:matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
输出:[[0,0,0,0],[0,4,5,0],[0,3,1,0]]
提示:
- m == matrix.length
- n == matrix[0].length
- 1 <= m, n <= 200
- -231 <= matrix[i][j] <= 231 - 1
解题思路:
1、对matrix数组的有效性进行判断,需存在且不为空;
2、定义行标数组r,用于存储0值的行号,列标c,用于存储0值的列号;
3、遍历数组,r,c存储查询到数据0的位置;
4、将存在0值的行、列全部置0,这里对部分原始数据进行了覆盖(原地算法);
5、返回修改后的matrix。
请在以下选项中选择
A 、
返回值: [[0, 0, 0, 0], [0, 4, 5, 0], [0, 3, 1, 0]] 但有逻辑错误。
class Solution(object):
def setZeroes(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: void Do not return anything, modify matrix in-place instead.
"""
if not matrix:
return
m = len(matrix)
#应为:if m == 0:
if m <= 0:
return
r = []
c = []
n = len(matrix[0])
for i in range(m):
for j in range(n):
if matrix[i][j] == 0:
r.append(i)
c.append(j)
r = set(r)
c = set(c)
for i in r:
for j in range(n):
matrix[i][j] = 0
for i in range(m):
for j in c:
matrix[i][j] = 0
return matrix
# %%
s = Solution()
print(s.setZeroes(matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]))
B、
if or matrix 语法错误
class Solution(object):
def setZeroes(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: void Do not return anything, modify matrix in-place instead.
"""
#应为:if not matrix:
if or matrix:
return
m = len(matrix)
if m == 0:
return
r = []
c = []
n = len(matrix[0])
for i in range(m):
for j in range(n):
if matrix[i][j] == 0:
r.append(i)
c.append(j)
r = set(r)
c = set(c)
for i in r:
for j in range(n):
matrix[i][j] = 0
for i in range(m):
for j in c:
matrix[i][j] = 0
return matrix
# %%
s = Solution()
print(s.setZeroes(matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]))
C、正确代码及详细解析
输出:[[0, 0, 0, 0], [0, 4, 5, 0], [0, 3, 1, 0]]
class Solution(object):
def setZeroes(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: void Do not return anything, modify matrix in-place instead.
"""
#确保matrix存在且不为空
if not matrix:
return
m = len(matrix)
if m == 0:
return
#list需先定义
r = [] #定义行标,用于存储0值的行号
c = [] #定义列标,用于存储0值的列号
#提取列数据长度并定义为n
n = len(matrix[0])
#遍历数组,行,列循环
for i in range(m):
for j in range(n):
#遍历数组,r,c存储查询到数据0的位置
if matrix[i][j] == 0:
r.append(i)
c.append(j)
#去重后,后期可以用r,c索引到0的位置
# 后续按题意要求,分别对行列进行循环置0处理
r = set(r)
c = set(c)
#将存在0值的行全部置0,这里对部分原始数据进行了覆盖(即第一行全部置0)
for i in r:
for j in range(n):
matrix[i][j] = 0
#行遍历,
for i in range(m):
#将0值存在的列全部置0,满足题意要求
for j in c:
matrix[i][j] = 0
return matrix
# %%
s = Solution()
print(s.setZeroes(matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]))
D
输出值:
[[0, 1, 2, 0], [3, 4, 5, 2], [1, 3, 1, 5]]
class Solution(object):
def setZeroes(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: void Do not return anything, modify matrix in-place instead.
"""
if not matrix:
return
m = len(matrix)
if m == 0:
return
r = []
c = []
n = len(matrix[0])
for i in range(m):
for j in range(n):
if matrix[i][j] < 0:
r.append(i)
c.append(j)
r = set(r)
c = set(c)
for i in r:
for j in range(n):
matrix[i][j] = 0
for i in range(m):
for j in c:
matrix[i][j] = 0
return matrix
# %%
s = Solution()
print(s.setZeroes(matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]))
#输出:
# [[0, 1, 2, 0], [3, 4, 5, 2], [1, 3, 1, 5]]