在LeetCode的热门100题中,有一道题目是“矩阵置零”(Matrix Zeroes),题目编号为135。该题要求给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列中所有元素都设为 0。你需要实现一个高效的算法来完成这个任务。
解题思路
为了解决这个问题,我们可以采用以下策略:
标记法:
遍历矩阵,对于每个为0的元素,我们标记其所在行和列的第一个元素(通常是左上角元素)。
再次遍历矩阵,如果某个元素所在的行或列被标记过,则将该元素置为0。
使用额外数组:
维护两个数组,分别记录每行和每列是否有0。
遍历矩阵,根据元素值更新这两个数组。
最后根据这两个数组更新原矩阵。
使用第一行和第一列:
直接在原矩阵的第一行和第一列记录该行或列是否有0。
注意处理好第一行和第一列本身是否需要被置零的情况。
方法3:使用第一行和第一列
这个方法利用了矩阵的第一行和第一列来记录哪些行和列需要被置零,这样可以避免使用额外的空间。
Python代码实现:
def setZeroes(matrix):
rows = len(matrix)
cols = len(matrix[0])
first_row_has_zero = False
first_col_has_zero = False
# 检查第一行是否有0
if 0 in matrix[0]:
first_row_has_zero = True
# 检查第一列是否有0
for i in range(1, rows):
if matrix[i][0] == 0:
first_col_has_zero = True
matrix[i][0] = 1 # 使用1来标记,避免与实际值混淆
# 使用第一行和第一列来标记需要置零的行列
for i in range(1, rows):
for j in range(1, cols):
if matrix[i][j] == 0:
matrix[i][0] = 0 # 标记第i行需要置零
matrix[0][j] = 0 # 标记第j列需要置零
# 根据标记置零
for i in range(1, rows):
for j in range(1, cols):
if matrix[i][0] == 0 or matrix[0][j] == 0:
matrix[i][j] = 0
# 处理第一行和第一列本身是否需要被置零
if first_row_has_zero:
for j in range(cols):
matrix[0][j] = 0
if first_col_has_zero:
for i in range(rows):
matrix[i][0] = 0
# Example usage:
matrix = [
[1, 1, 1],
[1, 0, 1],
[1, 1, 1]
]
setZeroes(matrix)
print(matrix) # Output: [[1, 0, 1], [0, 0, 0], [1, 0, 1]]
说明:
这个方法通过巧妙地利用矩阵的第一行和第一列来记录哪些行和列需要被置零,避免了使用额外的空间。这种方法在空间复杂度上非常高效(仅使用常数额外空间)。同时,通过先处理第一行和第一列的特殊情况(是否需要置零),可以确保整个算法的正确性。