【刷题日记】73. 矩阵置零

简介: 【刷题日记】73. 矩阵置零

一、题目描述:

今天来做一个二维数组的题目,矩阵置零

image.png

二、这道题考察了什么思想?你的思路是什么?

题目对我们的要求很明确也很简单,需要我们根据条件,将题目给出的二维矩阵对应的位置修改为 0

条件是:

当原矩阵的的某个位置数字为 0 的时候,那么这个位置对应的一行,和一列全部都需要变成 0

分析

这个题目看的出来,相对比较简单,而且看完题目,相信我们很快就会有思路,可能不是最优解,范式至少我们能够第一时间想出解决的方式,例如

看到题目,就能很容易想到,既然需要在原矩阵上修改值,那么我们就不能每一步都读取原有矩阵来判断是否需要按照条件来将矩阵的行列变成 0 , 因此我们需要用一个相应的一维数组来标记一下某一行是否需要全 0,某一列是否需要全 0

例如示例二中:

image.png

我们就需要这样的两个一维数组来进行标记

标记行的数组 0 1 2
true false false
标记列的数组 0 1 2 3
true false false true

那么当我们遍历二维矩阵的时候,实际上去校验一下当前位置对应的行或者列是否需要全部为 0 ,若是,则将当前位置的数值赋值为 0 即可

其实到这里,我们本应就可以编码了,但是我们继续看题,题目需要我们用更小的空间复杂度来解决这个题,因为本次我们第一时间想到的方式,空间复杂度是 O(m+n),其中 m 为行数组,n 为列数组的空间

进阶

那我们就要办法优化一下空间复杂度,既然上述我们是用了两个一维数组来进行标记,那么我们为了降低时间复杂度,是否可以用两个变量来标记呢?思考思考

还是以示例 2 为例:

image.png

  1. 我们遍历二维矩阵,记录一下当前矩阵的第一行,第一列是否需要为 0 ,记录为 row0 和 col0,很明显,该示例的记录结果为
row0 true
col0 true
  1. 我们开始遍历二维矩阵,判断当前位置是否为 0 ,若为零,则将原二维矩阵对应的第 0 行,和第0 列对应的位置赋值为 0 ,例如得到如下结果,发现对于本案例没啥变化,这一步主要是为了给我们的第0 行 和第 0 列进行赋值的
0 1 2 0
3 4 5 2
1 3 1 5
  1. 再遍历一次二维矩阵,这个时候,我们校验的是,当前的位置对应的第 0 行,和第0 列对应的位置是否为 0 ,若是,则将当前位置赋值为 0,得到如下结果
0 1 2 0
3 4 5 0
1 3 1 0
  1. 判断 row0 ,和 col0 是否为 true,若是,则将第 0 行 或者第0 列全部赋值为 0,这个是表示最开始原矩阵中就需要将第 0 行或的第 0 列全部赋值为 0 ,放在现在才做,是为了不影响前面步骤的进行, 得到如下结果
0 0 0 0
0 4 5 0
0 3 1 0

看到这里,xdm 应该看明白了这种方式了,我们只引入了常数级别的空间消耗,满足题目的进阶要求,一起来撸代码吧

三、编码

根据上述逻辑和分析,我们就可以翻译成如下代码

  • 严格按照上述分析的步骤来,不能跳步骤,直接翻译成代码即可

编码如下:

func setZeroes(matrix [][]int)  {
    // 先初始化我们的行列标记,标记第一行和第一列是否有 0
    n, m := len(matrix), len(matrix[0])
    row0, col0 := false, false
     for _, v := range matrix[0] {
        if v == 0 {
            row0 = true
            break
        }
    }
    for _, r := range matrix {
        if r[0] == 0 {
            col0 = true
            break
        }
    }
    // 开始正式遍历二维矩阵,查看当前数字是否为 0, 若为 0 ,则把当前位置对应第 0 行 和第 0 列 赋值为 0
     for i := 1; i < n; i++ {
        for j := 1; j < m; j++ {
            if matrix[i][j] == 0 {
                matrix[i][0] = 0
                matrix[0][j] = 0
            }
        }
    }
    // 再遍历 1 次二维矩阵,校验到当前位置对应的第 0 行,或者第 0 列是 0 ,则当前位置直接赋值为 0
    for i := 1; i < n; i++ {
        for j := 1; j < m; j++ {
            if matrix[i][0] == 0 || matrix[0][j] == 0 {
                matrix[i][j] = 0
            }
        }
    }
    // 最后,我们确认一下最开始我们校验的第 0 行 和 第 0 列是不是一开始就是有 0,若有,则这一行,或者这一列都是赋值为 0
    if row0 {
        for j := 0; j < m; j++ {
            matrix[0][j] = 0
        }
    }
    if col0 {
        for _, r := range matrix {
            r[0] = 0
        }
    }
}

四、总结:

image.png

本次解法文章内容中也有说到,空间复杂度是 O(1) ,这个就不过多说明, 时间复杂度也是很明确的,我们最多就是遍历了二维矩阵,因此时间复杂度是 O(mn) ,m 为行,n 为列

原题地址:73. 矩阵置零

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

image.png

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~

相关文章
|
8月前
【一刷《剑指Offer》】面试题 20:顺时针打印矩阵
【一刷《剑指Offer》】面试题 20:顺时针打印矩阵
|
8月前
【错题集-编程题】dd爱框框(同向双指针 / 滑动窗口)
【错题集-编程题】dd爱框框(同向双指针 / 滑动窗口)
学C的第八天(完成猜字谜游戏复习之前的内容;了解goto转向语句;补充知识点;练习,学习试除法和辗转相除法)-2
3.写一个代码,打印100-200之间的素数:(新思路:试除法) (判断i是否为素数:用 2到i-1 之间的数字去试除 i,如果能整除则i不是素数)
105 0
|
8月前
|
Java Go C++
Java每日一练(20230417) N 皇后、搜索二维矩阵、发奖金问题
Java每日一练(20230417) N 皇后、搜索二维矩阵、发奖金问题
54 0
Java每日一练(20230417) N 皇后、搜索二维矩阵、发奖金问题
|
8月前
|
算法 Java
刷题专栏(二十八):找到所有数组中消失的数字
刷题专栏(二十八):找到所有数组中消失的数字
130 4
|
C语言
【C语言刷题】喝汽水问题、上三角矩阵判定以及矩阵相等判定
【C语言刷题】喝汽水问题、上三角矩阵判定以及矩阵相等判定
94 0
【C语言刷题】喝汽水问题、上三角矩阵判定以及矩阵相等判定
|
C语言
学C的第八天(完成猜字谜游戏复习之前的内容;了解goto转向语句;补充知识点;练习,学习试除法和辗转相除法)-1
复习之前学C的内容: 猜数字游戏: 1. 电脑会随机生成一个数 2. 猜数字: a> 猜大了,提醒猜大了,继续猜 b> 猜小了,提醒猜小了,继续猜 c> 猜对了,恭喜你,猜对了,结束游戏 3. 玩完一把不过瘾可以继续玩,不用退出程序
|
存储 索引 Cloud Native
【刷题日记】498. 对角线遍历
本次刷题日记的第 65 篇,力扣题为:498. 对角线遍历,中等
|
索引 Cloud Native
【刷题日记】954. 二倍数对数组
本次刷题日记的第 21 篇,力扣题为:954. 二倍数对数组 ,中等
|
测试技术 Cloud Native
【刷题日记】532. 数组中的 k-diff 数对
本次刷题日记的第 67 篇,力扣题为:532. 数组中的 k-diff 数对,中等