草庐IT

【每日一好题】这么经典的题你不能不会:矩阵置零

不一样的烟火a 2023-04-04 原文

文章目录

🍁前言

🧧一、题目描述

🏮二、思路解析(最优解法)

🧨三、代码实现(内有超详细的注释)

🦀总结


🍁前言

大家好啊,我是不一样的烟火a,今天我要为大家分享一道好题,这道题也是一道常考题,所以大家务必掌握哦。为了避免以后忘了时再想看就找不到了,所以建议收藏。🦀最后提前祝大家国庆节快乐。


🧧一、题目描述

给定一个 m x n  的矩阵,如果一个元素为 ,则将其所在行和列的所有元素都设为 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
  • -2^31 <= matrix[i][j] <= 2^31 - 1

进阶:

  • 一个直观的解决方案是使用  O(mn) 的额外空间,但这并不是一个好的解决方案。
  • 一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。
  • 你能想出一个仅使用常量空间的解决方案吗?

快速跳转题目:矩阵置零

🏮二、思路解析(最优解法)

思路:

  • 我们可以用两个数组分别标记矩阵里面0元素的横坐标和纵坐标。我们用两个数组的下标来代替矩阵里面0元素的下标即可,把两个数组的某个位置的元素置为0即为标记。我们遍历一遍矩阵,遇到0元素,我们就将两个数组对应下标位置设为0进行标记。

  • 我们将矩阵中所有0元素的横纵坐标都标记后,我们这时再遍历一遍矩阵,如果发现当前元素的横坐标或者纵坐标被标记过,那么就将当前元素设置为0。

  • 但是我们如果单独创建2个数组来标记0元素的横纵坐标的话,空间复杂度就为O(m + n) 了,所以我们可以直接将矩阵的第一行用来标记0元素的横坐标,用矩阵的第一列来标记0元素的纵坐标。这样就可以将空间复杂度降为O(1)了。但是我们这时又需要考虑第一行或者第一列是否本身就存在0元素,如果第一行或第一列本身就存在0元素,我们就要将第一列或第一行的所有元素置为0,所以我们需要设置2个flag来标记一下第一行和第一列是否本身就存在0元素。如果我们再想一想,就可以发现,我们其实只用设置一个flag来标记第一列是否本身就存在0元素即可,因为第一列的第一个元素就可以当flag用,如果第一行本身存在0元素,我们在遍历第一行的时候就会将第一列第一个元素标记为0,这样就节省了一个变量的大小。

解题步骤:

1.初始状态:由于第一列中本身就存在0元素,所以我们将flag设置为true,到最后我们就会将第一列所有元素置成0。

2.我们用第一列和第一行来标记0元素的横纵坐标。

3.我们从最后一行,每行的第二列开始遍历矩阵,只要当前元素的横纵坐标有一个被标记,我们就将当前元素置为0。为什么要从最后一行开始遍历:我们遍历的时候需要从最后一行向上遍历,不要忘我们第一行是用来标记0元素的横坐标的,如果从第一行开始遍历,就有可能将标记的0元素横坐标改变。为什么要从第二列开始遍历:同样第一列是用来存储0元素的纵坐标的,所以我们等一行的其他列都遍历完后再回过头来看第一列,当一行的其他列都遍历完,最后我们判断flag是否为true,也就是判断第一列原本有没有0元素存在,如果flag为true,那么我们就将第一列的元素置为0。

🧨三、代码实现(内有超详细的注释)

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        // int flag_row0 = false; // 用于标记第一行是否有0,可以用第一列的第一个元素代替,从而减少了一个变量


        int flag_col0 = false; // 用于标记第一列是否有0
        int row = matrix.size(); // 一共有多少行
        int col = matrix[0].size(); // 一共有多少列

        // 遍历一遍矩阵
        // 用第一行和第一列标记矩阵中0元素的坐标
        // 并且判断第一列是否本身就存在0
        for (int i = 0; i < row; ++i)
        {
            // 只要第一列存在一个0,就将第一列标记
            if (!matrix[i][0])
            {
                flag_col0 = true;
            }

            // 标记每个0元素的下标
            // 由于第一列已经单独判断了,所以这里只用从第二列开始遍历
            for (int j = 1; j < col; ++j)
            {
                // 如果当前元素为0,就将它的横纵坐标分别在第一行和第一列中进行标记
                if (matrix[i][j] == 0)
                {
                    // 注意:这里的i为纵坐标,j为横坐标
                    matrix[0][j] = 0; // 第一行用于标记横坐标
                    matrix[i][0] = 0; // 第一列用于标记纵坐标
                }
            }
        }

        // 再遍历一遍矩阵,只要当前元素的横坐标、纵坐标有一个被标记过,就将其置为0
        // 注意:这时遍历时就不能从第一列开始遍历了,如果第一列本身存在0,我们遍历完第一列就将第一列全部置成0了,导致我们刚才标记的坐标改变
        // 所以我们需要从后向前遍历。
        // 每行的第一个元素也要最后判断,如果先判断的话就跟先遍历第一行是一样的了
        // 如果第一列本身存在0,那么从每行第一个元素开始遍历,就会将第一个元素置成0,导致我们标记的坐标改变。

        for (int i = row - 1; i >= 0; --i)
        {
            // 由于下面会单独判断第一列元素,所以这里还是从第二列开始遍历
            for (int j = 1; j < col; ++j)
            {
                // 如果当前元素的横坐标、纵坐标有一个被标记过,就将其置为0
                if (!matrix[0][j] || !matrix[i][0])
                {
                   matrix[i][j] = 0;
                }
            }

            // 判断第一列是否本身就有0,如果有就将第一列的元素置成0,如果没有就不管了
            if (flag_col0)
            {
                 matrix[i][0] = 0;
            }
        }
    }
};

🦀总结

今天分享的题就到这了,相信大家都能够看懂,如果大家有什么解决不了的问题,欢迎大家评论区留言或者私信告诉我。如果感觉对自己有用的话,可以点个赞或关注鼓励一下博主,我会越做越好的,感谢各位的支持。🦀最后再次祝大家国庆节快乐。

有关【每日一好题】这么经典的题你不能不会:矩阵置零的更多相关文章

  1. ruby - Highline 询问方法不会使用同一行 - 2

    设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案

  2. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  3. 旋转矩阵的几何意义 - 2

    点向量坐标矩阵的几何意义介绍旋转矩阵的几何含义之前,先介绍一下点向量坐标矩阵的几何含义点:在一维空间下就是一个标量,如同一条直线上,以任意某一个位置为0点,以一定的尺度间隔为1,2,3...,相反方向为-1,-2,-3...;如此就形成了一维坐标系,这时候任何一个点都可以用一个数值表示,如点p1=5,即即从原点出发沿着x轴正方向移动5个尺度;点p2=-3,负方向移动3个尺度;     在一维坐标系上过原点做垂直于一维坐标系的直线,则形成了二维坐标系,此时描述一个点需要两个数值来表示点p3=(3,2),即从原点出发沿着x轴正方向移动3个尺度,在此基础上沿着y轴正方向移动两个尺度的位置就是点p3。

  4. 7个大一C语言必学的程序 / C语言经典代码大全 - 2

    嗨~大家好,这里是可莉!今天给大家带来的是7个C语言的经典基础代码~那一起往下看下去把【程序一】打印100到200之间的素数#includeintmain(){ inti; for(i=100;i 【程序二】输出乘法口诀表#includeintmain(){inti;for(i=1;i 【程序三】判断1000年---2000年之间的闰年#includeintmain(){intyear;for(year=1000;year 【程序四】给定两个整形变量的值,将两个值的内容进行交换。这里提供两种方法来进行交换,第一种为创建临时变量来进行交换,第二种是不创建临时变量而直接进行交换。1.创建临时变量来

  5. Hive SQL 五大经典面试题 - 2

    目录第1题连续问题分析:解法:第2题分组问题分析:解法:第3题间隔连续问题分析:解法:第4题打折日期交叉问题分析:解法:第5题同时在线问题分析:解法:第1题连续问题如下数据为蚂蚁森林中用户领取的减少碳排放量iddtlowcarbon10012021-12-1212310022021-12-124510012021-12-134310012021-12-134510012021-12-132310022021-12-144510012021-12-1423010022021-12-154510012021-12-1523.......找出连续3天及以上减少碳排放量在100以上的用户分析:遇到这类

  6. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  7. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  8. ruby-on-rails - prawnto 显示新页面时不会中断的表格 - 2

    我有可变数量的表格和可变数量的行,我想让它们一个接一个地显示,但如果表格不适合当前页面,请将其放在下一页,然后继续。我已将表格放入事务中,以便我可以回滚然后打印它(如果高度适合当前页面),但我如何获得表格高度?我现在有这段代码pdf.transactiondopdf.table@data,:font_size=>12,:border_style=>:grid,:horizontal_padding=>10,:vertical_padding=>3,:border_width=>2,:position=>:left,:row_colors=>["FFFFFF","DDDDDD"]pdf.

  9. ruby-on-rails - Ruby rand() 不能接受变量? - 2

    我对此有点困惑。我在RoR项目中的最终目标是从我的数据库中获取单个随机配置文件。我想它应该是这样的:@profile=Profile.find_by_user_id(rand(User.count))它一直抛出错误,因为user_id0不存在,所以我把它的一部分拿出来检查发生了什么:@r=rand(User.count)每次都返回0。发生什么了?我注册了5个假用户和5个相关配置文件来测试这个。如果我将Profile.find_by_user_id(rand(User.count))重写为Profile.find_by_user_id(3)它工作得很好。User.count也在工作。所以

  10. ruby - 为什么我不能从 ruby​​ 中的选定键创建新的散列? - 2

    这个问题困扰了我一段时间。这不是一件困难的事情,但我不知道为什么没有简单的方法来做到这一点,我敢打赌有但我没有看到。我只想取一个散列,像这样:cars={:bob=>'Pontiac',:fred=>'Chrysler',:lisa=>'Cadillac',:mary=>'Jaguar'}然后做类似的事情cars[:bob,:lisa]得到{:bob=>'Pontiac',:lisa=>'Cadillac'}我这样做了,效果很好:classHashdefpick(*keys)Hash[select{|k,v|keys.include?(k)}]endendruby-1.8.7-p249

随机推荐