刷题的日常-零矩阵

66 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情

刷题的日常-2022年9月30日

一天一题,保持脑子清爽

零矩阵

来自leetcode的 面试题 01.08 题,题意如下:

编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。

示例1

输入:
[
  [1,1,1],
  [1,0,1],
  [1,1,1]
]
输出:
[
  [1,0,1],
  [0,0,0],
  [1,0,1]
]

示例2

输入:
[
  [0,1,2,0],
  [3,4,5,2],
  [1,3,1,5]
]
输出:
[
  [0,0,0,0],
  [0,4,5,0],
  [0,3,1,0]
]

理解题意

我们可以从题意中提取的条件如下:

  • 题目给出一个矩阵
  • 要求我们对矩阵填零
  • 如果某个位置是0,那么它对应的列和行都应该是0
  • 必须在原矩阵上修改,不允许返回值

做题思路

我们可以先遍历数组找到需要填充的行和列,找到之后再通过找出的行和列对矩阵进行填充,步骤如下:

  • 首先开辟两个布尔数组,用于保存行或者是列出现0的位置
  • 遍历数组,如果某个位置出现0,那么就将当前行和列的位置标记一下
  • 标记完成之后我们对两个布尔数组进行遍历
    • 如果当前行没有被标记为0,则直接跳过,如果是被标记过的,用0填充
    • 如果当前列没有被标记为0,则直接跳过,如果是被标记过的,用0填充
  • 流程解释

代码实现

因为需要开辟两个数组进行记录,所以空间复杂度为O(m + n)。 代码实现如下:

public class Solution {

    public void setZeroes(int[][] matrix) {
        int[] col;
        boolean[] rowMap = new boolean[matrix.length], colMap = new boolean[matrix[0].length];
        for (int r = 0; r < matrix.length; r++) {
            col = matrix[r];
            for (int c = 0; c < col.length; c++) {
                if (col[c] == 0) {
                    colMap[c] = rowMap[r] = true;
                }
            }
        }
        for (int i = 0; i < rowMap.length; i++) {
            if (!rowMap[i]) {
                continue;
            }
            Arrays.fill(matrix[i], 0);
        }
        for (int i = 0; i < colMap.length; i++) {
            if (!colMap[i]) {
                continue;
            }
            for (int r = 0; r < matrix.length; r++) {
                matrix[r][i] = 0;
            }
        }
    }

}

image.png