Java算法题-解析 "矩阵置零" 算法问题
题目:
给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。要求在原地修改矩阵。
引言:
"矩阵置零" 是一个关于数组操作和标记的问题。解决这个问题需要对数组的遍历和修改有一定的理解,同时需要找到一种方法来标记需要置零的行和列。通过解答这个问题,我们可以提升对数组操作和标记的考虑,同时也能拓展对空间复杂度的控制。
算法思路:
为了实现矩阵置零,我们可以使用矩阵的第一行和第一列来作为标记数组。具体思路如下:
- 首先遍历矩阵,如果某个元素为 0,将其所在行的第一个元素标记为 0,将其所在列的第一个元素标记为 0。
- 继续遍历矩阵,对除第一行和第一列以外的元素,如果其所在行的第一个元素或所在列的第一个元素为 0,则将该元素置为 0。
- 根据第一行和第一列的标记,将对应的行和列全部置为 0。
- 最后根据第一行和第一列的标记,将第一行和第一列是否需要置零。
代码实现:
以下是使用 Java 实现的 "矩阵置零" 算法的示例代码:
public class SetMatrixZeroes {
public void setZeroes(int[][] matrix) {
int m = matrix.length;
int n = matrix[0].length;
boolean firstRowZero = false;
boolean firstColZero = false;
// Check if first row and first column need to be zeroed
for (int i = 0; i < m; i++) {
if (matrix[i][0] == 0) {
firstColZero = true;
break;
}
}
for (int j = 0; j < n; j++) {
if (matrix[0][j] == 0) {
firstRowZero = true;
break;
}
}
// Use first row and first column to mark zero rows and columns
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;
}
}
}
// Zero rows and columns except for first row and first column
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;
}
}
}
// Zero first row and first column if needed
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;
}
}
}
}
算法分析:
- 时间复杂度:遍历矩阵三次,所以时间复杂度为 O(m * n),其中 m 和 n 分别是矩阵的行数和列数。
- 空间复杂度:使用了两个标记变量来记录第一行和第一列是否需要置零,所以空间复杂度为 O(1)。
示例和测试:
假设给定矩阵 matrix = [[1,1,1],[1,0,1],[1,1,1]]
,根据算法,置零后的矩阵为 [[1,0,1],[0,0,0],[1,0,1]]
。
我们可以使用以下代码进行测试:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
SetMatrixZeroes solution = new SetMatrixZeroes();
int[][] matrix = {{1, 1, 1}, {1, 0, 1}, {1, 1, 1}};
solution.setZeroes(matrix);
System.out.println("Zeroed matrix:");
for (int[] row : matrix) {
System.out.println(Arrays.toString(row));
}
}
}
总结:
"矩阵置零" 算法题要求将矩阵中的 0 所在的行和列都置零,是一个关于数组操作和标记的问题。通过实现这个算法,我们可以提升对数组操作和标记的考虑,同时也能拓展对空间复杂度的控制。这个问题强调了如何使用矩阵的第一行和第一列来标记需要置零的行和列。