题目描述
给定一个
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
-
<= matrix[i][j] <=
- 1
进阶:
- 一个直观的解决方案是使用
O(mn)
的额外空间,但这并不是一个好的解决方案。- 一个简单的改进方案是使用
O(m + n)
的额外空间,但这仍然不是最好的解决方案。- 你能想出一个仅使用常量空间的解决方案吗?
解题思路
-
检查第一行和第一列:首先检查矩阵的第一行和第一列是否包含
0
。这两部分特殊处理,因为它们将用作标记其他行和列的状态。 -
标记其他行和列:遍历矩阵中除了第一行和第一列之外的所有元素。如果某个元素为
0
,则将其所在的行和列的首位置为0
。即,matrix[i][0]
和matrix[0][j]
。 -
将标记的行和列置为
0
:遍历矩阵,将那些被标记为0
的行和列中的所有元素设置为0
。 -
处理第一行和第一列:根据步骤 1 中记录的标志,处理第一行和第一列。如果第一行或第一列需要被置为
0
,则逐一设置。
复杂度分析
- 时间复杂度:O(m * n),因为每个元素最多被访问和修改两次。
- 空间复杂度:O(1),除了输入矩阵外,不使用额外的空间。
代码实现
package org.zyf.javabasic.letcode.hot100.matrix;
/**
* @program: zyfboot-javabasic
* @description: 矩阵置零
* @author: zhangyanfeng
* @create: 2024-08-21 22:46
**/
public class SetZeroesSolution {
public void setZeroes(int[][] matrix) {
int m = matrix.length; // 获取矩阵的行数
int n = matrix[0].length; // 获取矩阵的列数
// 步骤 1: 判断第一行和第一列是否需要被置为 0
boolean firstRowZero = false;
boolean firstColZero = false;
// 检查第一行是否有 0
for (int j = 0; j < n; j++) {
if (matrix[0][j] == 0) {
firstRowZero = true;
break;
}
}
// 检查第一列是否有 0
for (int i = 0; i < m; i++) {
if (matrix[i][0] == 0) {
firstColZero = true;
break;
}
}
// 步骤 2: 使用第一行和第一列作为标记,记录其他行和列的 0
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; // 标记列
}
}
}
// 步骤 3: 根据标记将相应的行和列置为 0
for (int i = 1; i < m; i++) {
if (matrix[i][0] == 0) {
for (int j = 1; j < n; j++) {
matrix[i][j] = 0;
}
}
}
for (int j = 1; j < n; j++) {
if (matrix[0][j] == 0) {
for (int i = 1; i < m; i++) {
matrix[i][j] = 0;
}
}
}
// 步骤 4: 根据之前的标记将第一行和第一列置为 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;
}
}
}
public static void main(String[] args) {
SetZeroesSolution solution = new SetZeroesSolution();
// 测试用例 1
int[][] matrix1 = {
{1, 1, 1},
{1, 0, 1},
{1, 1, 1}
};
solution.setZeroes(matrix1);
printMatrix(matrix1); // 输出: [[1, 0, 1], [0, 0, 0], [1, 0, 1]]
// 测试用例 2
int[][] matrix2 = {
{0, 1, 2, 0},
{3, 4, 5, 2},
{1, 3, 1, 5}
};
solution.setZeroes(matrix2);
printMatrix(matrix2); // 输出: [[0, 0, 0, 0], [0, 4, 5, 0], [0, 3, 1, 0]]
}
// 辅助函数:打印矩阵
private static void printMatrix(int[][] matrix) {
for (int[] row : matrix) {
for (int value : row) {
System.out.print(value + " ");
}
System.out.println();
}
}
}
具体可参考:https://zyfcodes.blog.csdn.net/article/details/141401712