今天本来准备好好补一下智能客服项目的,但因为纳新网站占了不分时间没弄成,简单做了两个算法,看了下八股
问题描述

核心思路
-
标记需清零的行列
- 创建两个布尔数组
arr(长度=行数)和brr(长度=列数),分别标记需要清零的行和列。 - 遍历矩阵,遇到元素为 0 时,将对应行索引在
arr中标记为true,列索引在brr中标记为true。
- 创建两个布尔数组
-
执行清零操作
- 再次遍历矩阵,若当前行或列被标记为需清零,则将元素置为 0。
时间复杂度 :O(m × n) 空间复杂度:O(m + n)(两个额外数组)
代码实现
java
class Solution {
public void setZeroes(int[][] matrix) {
int x= matrix.length;
int y=matrix[0].length;
boolean[] arr = new boolean[x];
boolean[] brr=new boolean[y];
for(int i=0;i<x;i++){
for(int j=0;j<y;j++){
if(matrix[i][j]==0){
arr[i]=brr[j]=true;
}
}
}
for(int i=0;i<x;i++){
for(int j=0;j<y;j++){
if(arr[i]||brr[j]){
matrix[i][j]=0;
}
}
}
}
}
关键步骤解析
-
初始化标记数组
rowZero数组标记需清零的行(长度为m),colZero数组标记需清零的列(长度为n)。- 默认值均为
false,表示初始时无需清零。
-
第一次遍历:标记清零位置
- 遍历每个元素
matrix[i][j],若值为 0,则设置rowZero[i] = true和colZero[j] = true。 - 示例 : 矩阵
[[1,0,1],[1,1,1],[1,1,0]]的标记结果为:rowZero = [true, false, true](第0行和第2行需清零)colZero = [true, false, true](第0列和第2列需清零)
- 遍历每个元素
-
第二次遍历:执行清零
- 遍历每个元素,若
rowZero[i]或colZero[j]为true,则置零。 - 逻辑解释 :
- 若当前行需清零(
rowZero[i]==true),则无论列是否标记,该行所有元素清零。 - 若当前列需清零(
colZero[j]==true),则无论行是否标记,该列所有元素清零。
- 若当前行需清零(
- 遍历每个元素,若
示例演示
输入矩阵:
java
[
[1, 0, 1],
[1, 1, 1],
[1, 1, 0]
]
标记过程:
- 遍历到
(0,1)=0→ 标记rowZero=true,colZero=true。 - 遍历到
(2,2)=0→ 标记rowZero=true,colZero=true。
清零过程:
- 第0行:全部清零 →
[0,0,0] - 第2行:全部清零 →
[0,0,0] - 第1行:第1列被标记 →
[1,0,1]→ 但第1行未被标记,因此仅第1列清零 →[1,0,1]变为[1,0,1](实际不变)
输出矩阵:
java
[
[0, 0, 0],
[1, 0, 1], // 第1列被标记清零,其他元素保留
[0, 0, 0]
]
优化思考
虽然此解法空间复杂度为 O(m+n),但若追求 O(1) 空间,可将矩阵的第一行和第一列作为标记数组(需额外变量处理第一行/列的初始状态)。核心思想类似,但需注意边界条件,适合进阶挑战!
通过两个布尔数组的巧妙使用,我们高效地解决了矩阵置零问题。这种"标记-清零"的分步策略清晰易懂,是处理矩阵类问题的经典思路。