一、题目描述
给定一个 m x n
的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。
示例 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
-2^31 <= matrix[i][j] <= 2^31 - 1
二、解题思路
- 遍历整个矩阵,找到所有元素为0的位置,将它们的行和列的索引分别存储在两个集合中。
- 再次遍历矩阵,对于每个元素,如果它的行或列的索引在之前存储的集合中,就将该元素设为0。
三、具体代码
import java.util.HashSet;
import java.util.Set;
public class Solution {
public void setZeroes(int[][] matrix) {
int m = matrix.length;
int n = matrix[0].length;
Set<Integer> rows = new HashSet<>();
Set<Integer> cols = new HashSet<>();
// 遍历矩阵,找到所有元素为0的位置
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == 0) {
rows.add(i);
cols.add(j);
}
}
}
// 再次遍历矩阵,将元素设为0
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (rows.contains(i) || cols.contains(j)) {
matrix[i][j] = 0;
}
}
}
}
public static void main(String[] args) {
Solution solution = new Solution();
int[][] matrix1 = {{1, 1, 1}, {1, 0, 1}, {1, 1, 1}};
solution.setZeroes(matrix1);
for (int[] row : matrix1) {
for (int num : row) {
System.out.print(num + " ");
}
System.out.println();
}
int[][] matrix2 = {{0, 1, 2, 0}, {3, 4, 5, 2}, {1, 3, 1, 5}};
solution.setZeroes(matrix2);
for (int[] row : matrix2) {
for (int num : row) {
System.out.print(num + " ");
}
System.out.println();
}
}
}
四、时间复杂度和空间复杂度
1. 时间复杂度
- 遍历矩阵找到所有元素为0的位置需要 O(m * n) 时间,其中 m 是矩阵的行数,n 是矩阵的列数。
- 再次遍历矩阵将元素设为0也需要 O(m * n) 时间。
- 因此,总的时间复杂度是 O(m * n)。
2. 空间复杂度
- 使用了两个集合来存储需要置零的行和列的索引,每个集合的空间复杂度是 O(m + n),因为最坏的情况是矩阵的所有行或列都需要置零。
- 因此,总的空间复杂度是 O(m + n)。
五、总结知识点
-
二维数组:
matrix
是一个二维数组,用于存储矩阵中的元素。 -
HashSet:
HashSet
是 Java 中的一种集合实现,用于存储不重复的元素。在代码中,rows
和cols
是两个 HashSet 实例,分别用于存储需要置零的行和列的索引。 -
for 循环:用于遍历矩阵的行和列。
-
条件语句:
if
语句用于检查矩阵中的元素是否为0,以及行或列的索引是否在 HashSet 中。 -
集合操作:
add
方法用于向 HashSet 中添加元素,contains
方法用于检查 HashSet 是否包含某个元素。 -
数组访问:使用索引
i
和j
访问二维数组matrix
中的元素,并进行赋值操作。 -
算法思想:代码实现了原地算法,即不使用额外的矩阵来存储结果,而是直接在原矩阵上进行修改。
-
函数定义:
setZeroes
是一个公共方法,用于接收一个二维整数数组matrix
作为参数,并修改其内容。 -
主函数:
main
函数是程序的入口点,用于创建Solution
类的实例,调用setZeroes
方法,并打印修改后的矩阵。
以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。