Given an m x n
integer matrix called matrix
, if any element within the matrix is 0
, you must set its entire row and column to 0
's. You are required to perform this operation in-place, modifying the original matrix directly without creating a new one.
Here are a couple of examples to illustrate the problem:
Input:
matrix = [[1,1,1],[1,0,1],[1,1,1]]
Output:
[[1,0,1],[0,0,0],[1,0,1]]
Explanation: The element at matrix[1][1]
is 0
. Therefore, the entire second row and the entire second column should be set to 0
.
Input:
matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
Output:
[[0,0,0,0],[0,4,5,0],[0,3,1,0]]
Explanation: The elements at matrix[0][0]
and matrix[0][3]
are 0
. Therefore, the entire first row and the first and fourth columns should be set to 0
.
Consider the constraints:
m
is the number of rows in the matrix.n
is the number of columns in the matrix.1 <= m, n <= 200
-2^31 <= matrix[i][j] <= 2^31 - 1
How would you implement an in-place algorithm to solve this problem efficiently? Consider space complexity as a critical factor in your solution.
Given an m x n
integer matrix matrix
, if an element is 0
, set its entire row and column to 0
's. You must do it in place.
A brute force approach involves creating a copy of the matrix and then iterating through the original matrix. If we encounter a 0
in the original matrix, we set the corresponding row and column to 0
's in the copied matrix. Finally, we overwrite the original matrix with the modified copied matrix.
def set_matrix_zeroes_brute_force(matrix):
m = len(matrix)
n = len(matrix[0])
# Create a copy of the matrix
copied_matrix = [row[:] for row in matrix]
# Iterate through original matrix
for i in range(m):
for j in range(n):
if matrix[i][j] == 0:
# Set row and column to 0 in the copied matrix
for k in range(n):
copied_matrix[i][k] = 0
for k in range(m):
copied_matrix[k][j] = 0
# Overwrite the original matrix
for i in range(m):
for j in range(n):
matrix[i][j] = copied_matrix[i][j]
O(m * n * (m + n)), where m is the number of rows and n is the number of columns.
O(m * n) because we create a copy of the original matrix.
Instead of using O(m*n) space, we can use O(1) space. The idea is to use the first row and first column of the matrix as markers to indicate whether a row or column should be set to zero. Here's how it works:
row_has_zero
or col_has_zero
flags to true, respectively.matrix[i][j]
(where i > 0
and j > 0
), if it's zero, set matrix[i][0]
and matrix[0][j]
to zero. This marks that the i-th row and j-th column should be zeroed.matrix[i][0]
or matrix[0][j]
is zero, set matrix[i][j]
to zero.row_has_zero
is true, zero out the entire first row. If col_has_zero
is true, zero out the entire first column.def set_matrix_zeroes_optimal(matrix):
m = len(matrix)
n = len(matrix[0])
row_has_zero = False
col_has_zero = False
# Check if the first row contains a zero
for j in range(n):
if matrix[0][j] == 0:
row_has_zero = True
break
# Check if the first column contains a zero
for i in range(m):
if matrix[i][0] == 0:
col_has_zero = True
break
# Use the first row and first column as markers
for i in range(1, m):
for j in range(1, n):
if matrix[i][j] == 0:
matrix[i][0] = 0
matrix[0][j] = 0
# Zero out the rows and columns based on markers
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
# Zero out the first row if necessary
if row_has_zero:
for j in range(n):
matrix[0][j] = 0
# Zero out the first column if necessary
if col_has_zero:
for i in range(m):
matrix[i][0] = 0
O(m * n), where m is the number of rows and n is the number of columns. We iterate through the matrix a few times.
O(1), constant space, as we are modifying the matrix in-place.