0073. 矩阵置零【中等】
1. 📝 题目描述
给定一个 *m* x *n* 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用 原地算法。
示例 1:

txt
输入:matrix = [[1,1,1],[1,0,1],[1,1,1]]
输出:[[1,0,1],[0,0,0],[1,0,1]]1
2
2
示例 2:

txt
输入: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]]1
2
2
提示:
m == matrix.lengthn == matrix[0].length1 <= m, n <= 200-2^31 <= matrix[i][j] <= 2^31 - 1
进阶:
- 一个直观的解决方案是使用
O(*mn*)的额外空间,但这并不是一个好的解决方案。 - 一个简单的改进方案是使用
O(*m* + *n*)的额外空间,但这仍然不是最好的解决方案。 - 你能想出一个仅使用常量空间的解决方案吗?
2. 🎯 s.1 - 原地标记(首行首列复用)
c
void setZeroes(int** matrix, int matrixSize, int* matrixColSize) {
int m = matrixSize, n = matrixColSize[0];
int firstRowZero = 0, firstColZero = 0;
// 检查第一行、第一列是否有 0
for (int j = 0; j < n; j++)
if (matrix[0][j] == 0)
firstRowZero = 1;
for (int i = 0; i < m; i++)
if (matrix[i][0] == 0)
firstColZero = 1;
// 用第一行和第一列记录零的位置
for (int i = 1; i < m; i++)
for (int j = 1; j < n; j++)
if (matrix[i][j] == 0) {
matrix[i][0] = 0;
matrix[0][j] = 0;
}
// 根据标记置零
for (int i = 1; i < m; i++)
for (int j = 1; j < n; j++)
if (matrix[i][0] == 0 || matrix[0][j] == 0)
matrix[i][j] = 0;
// 处理第一行和第一列
if (firstRowZero)
for (int j = 0; j < n; j++)
matrix[0][j] = 0;
if (firstColZero)
for (int i = 0; i < m; i++)
matrix[i][0] = 0;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
js
/**
* @param {number[][]} matrix
* @return {void} Do not return anything, modify matrix in-place instead.
*/
var setZeroes = function (matrix) {
const m = matrix.length,
n = matrix[0].length
let firstRowZero = false,
firstColZero = false
// 检查第一行、第一列是否有 0
for (let j = 0; j < n; j++) if (matrix[0][j] === 0) firstRowZero = true
for (let i = 0; i < m; i++) if (matrix[i][0] === 0) firstColZero = true
// 用第一行和第一列记录零的位置
for (let i = 1; i < m; i++)
for (let j = 1; j < n; j++)
if (matrix[i][j] === 0) {
matrix[i][0] = 0
matrix[0][j] = 0
}
// 根据标记置零
for (let i = 1; i < m; i++)
for (let j = 1; j < n; j++)
if (matrix[i][0] === 0 || matrix[0][j] === 0) matrix[i][j] = 0
// 处理第一行和第一列
if (firstRowZero) for (let j = 0; j < n; j++) matrix[0][j] = 0
if (firstColZero) for (let i = 0; i < m; i++) matrix[i][0] = 0
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
py
class Solution:
def setZeroes(self, matrix: List[List[int]]) -> None:
m, n = len(matrix), len(matrix[0])
first_row_zero = any(matrix[0][j] == 0 for j in range(n))
first_col_zero = 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] = 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 first_row_zero:
for j in range(n):
matrix[0][j] = 0
if first_col_zero:
for i in range(m):
matrix[i][0] = 01
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
- 时间复杂度:
,遍历矩阵常数次 - 空间复杂度:
,利用矩阵自身首行首列作为标记,只使用常数额外空间
算法思路:
- 先用两个变量记录第一行和第一列是否本身含有 0
- 遍历矩阵(跳过首行首列),若
matrix[i][j] == 0,则将matrix[i][0]和matrix[0][j]标记为 0 - 根据首行首列的标记,将对应位置置 0
- 最后根据预存的变量,决定是否将第一行和第一列整体置 0