力扣 73. 矩阵置零

题目说明

给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用**原地算法。**

  • 一个直接的解决方案是使用 O(m**n) 的额外空间,但这并不是一个好的解决方案。
  • 一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。
  • 你能想出一个常数空间的解决方案吗?

示例

例1

1
2
3
4
5
6
7
8
9
10
11
12
输入: 
[
[1,1,1],
[1,0,1],
[1,1,1]
]
输出:
[
[1,0,1],
[0,0,0],
[1,0,1]
]

例2

1
2
3
4
5
6
7
8
9
10
11
12
输入: 
[
[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
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public void setZeroes(int[][] matrix) {
int row = matrix.length;
int column = matrix[0].length;
if(row == 1 && column ==1) { return; }

//定义两个变量分别表示首行及首列有没有零
int rowFirst = 1;
int columnFirst = 1;

for (int i = 0; i < row; i++) {
if(matrix[i][0] == 0) {
rowFirst = 0;
}
}
for (int i = 0; i < column; i++) {
if(matrix[0][i] == 0) {
columnFirst = 0;
}
}

//遍历非首行首列元素,遇零就将其对应的首行首列元素置零
for (int i = 1; i < row; i++) {
for (int j = 1; j < column; j++) {
if(matrix[i][j]==0) {
matrix[i][0] = 0;
matrix[0][j] = 0;
}
}
}

//根据首行首列元素将其后面的元素置为零
for (int i = 1; i < row; i++) {
if(matrix[i][0] == 0) {
for (int j = 1; j < column; j++) {
matrix[i][j] = 0;
}
}
}
for (int i = 1; i < column; i++) {
if(matrix[0][i] == 0) {
for (int j = 1; j < row; j++) {
matrix[j][i] = 0;
}
}
}

//再将首行首列原本有零的行列置零
if(rowFirst==0) {
for (int i = 0; i < row; i++) {
matrix[i][0] = 0;
}
}
if(columnFirst==0) {
for (int i = 0; i < column; i++) {
matrix[0][i] = 0;
}
}
}

时间和空间效率都还行,可见此解法还比较适合此题;

image.png

总结

本题是今天的每日一题,难度是为中等,感兴趣的朋友都可以去尝试一下,此题还有其他更多的解法,朋友们可以自己逐一尝试。