热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

LeetCode矩阵置零(73题)

LeetCode矩阵置零author:Jingdaidate:2020.09.30题目描述(73题)给定一个mxn的矩阵,如果一个元素
LeetCode 矩阵置零

@author:Jingdai
@date:2020.09.30

题目描述(73题)


给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法。

  • 示例输入:

[[1,1,1],[1,0,1],[1,1,1]
]

  • 示例输出:

[[1,0,1],[0,0,0],[1,0,1]
]


思路


看到题目,第一想法应该是使用两个集合分别记录哪些行和哪些列应该设置为0,当遍历到 matrix[i][j] 时,如果它等于 0 ,则在行集合中加入 i ,在列集合中加入 j ,即:

if (matrix[i][j] == 0) {rowSet.add(i);columnSet.add(j);
}

然后再遍历一遍数组,将对应的行和列中的元素都置为 0 ,即:

if (rowSet.contains(i) || columnSet.contains(j)) {matrix[i][j] = 0;
}

这种方法比较直观,也好理解,但是需要一个额外的(m+n) 大小的空间,这里使用另一种方法,仅使用常量大小的空间。

按上面方法的思路,我们需要记录哪一行和哪一列需要设置为 0 ,我们可以利用矩阵第 0 行和第 0 列的元素来记录,如下图:

在这里插入图片描述

matrix[1][1] 等于 0 时,就将它对应的行的首元素 matrix[1][0] 和对应列的首元素 matrix[0][1] 置为 0 ,这里注意到将对应的行和列的首元素置为 0 并不会影响之后的判断,因为你会发现遍历矩阵时, matrix[i][j] 永远在 matrix[0][j]matrix[i][0] 的后面,所以不会影响到之后的判断。遍历完整个矩阵后,再次遍历矩阵,将第 0 行中 0 元素对应的列全部置 0 ,将第 0 列中 0 元素对应的行全部置 0 。

好像这样就完了,但是其实有一个问题,看下图。

在这里插入图片描述

当 0 元素位于第 0 行或第 0 列时,如图中的 matrix[1][0]matrix[0][1] ,都会使 matrix[0][0] 变为 0 ,无法判断是第 0 行有 0 元素还是第 0 列有 0 元素,所以我们需要多余的变量记录第 0 行和第 0 列是否有 0 元素。

这里我们多设置一个 boolean 变量 isRow, 记录了第 0 行是否有零元素,在遍历第 0 行时,我们不修改 matrix 的值,如果第 0 行包含 0 ,就将 isRow 设置为 true ,其它和之前一样,而如果最后 matrix[0][0] 值为 0 ,则肯定是第 0 列包含 0 (或者它本身是 0,本身也在第 0 列),然后第二次遍历修改的时候先不修改第 0 行和第 0 列,之后根据 isRowmatrix[0][0] 的值来单独更新第 0 行和第 0 列。代码如下。


代码


public void setZeroes(int[][] matrix) {if (matrix.length &#61;&#61; 0) {return;}boolean isRow &#61; false;int row &#61; matrix.length;int column &#61; matrix[0].length;for (int i &#61; 0; i < row; i&#43;&#43;) {for (int j &#61; 0; j < column; j&#43;&#43;) {if (i &#61;&#61; 0) {if (matrix[i][j] &#61;&#61; 0) {isRow &#61; true;}} else {if (matrix[i][j] &#61;&#61; 0) {matrix[i][0] &#61; 0;matrix[0][j] &#61; 0;}}}}for (int i &#61; 1; i < row; i&#43;&#43;) {for (int j &#61; 1; j < column; j&#43;&#43;) {if (matrix[i][0] &#61;&#61; 0 || matrix[0][j] &#61;&#61; 0) {matrix[i][j] &#61; 0;}}}if (matrix[0][0] &#61;&#61; 0) {for (int i &#61; 1; i < row; i&#43;&#43;) {matrix[i][0] &#61; 0;}}if (isRow) {for (int j &#61; 0; j < column; j&#43;&#43;) {matrix[0][j] &#61; 0;}}
}


推荐阅读
  • 本文详细解析了JavaScript中相称性推断的知识点,包括严厉相称和宽松相称的区别,以及范例转换的规则。针对不同类型的范例值,如差别范例值、统一类的原始范例值和统一类的复合范例值,都给出了具体的比较方法。对于宽松相称的情况,也解释了原始范例值和对象之间的比较规则。通过本文的学习,读者可以更好地理解JavaScript中相称性推断的概念和应用。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • LeetCode笔记:剑指Offer 41. 数据流中的中位数(Java、堆、优先队列、知识点)
    本文介绍了LeetCode剑指Offer 41题的解题思路和代码实现,主要涉及了Java中的优先队列和堆排序的知识点。优先队列是Queue接口的实现,可以对其中的元素进行排序,采用小顶堆的方式进行排序。本文还介绍了Java中queue的offer、poll、add、remove、element、peek等方法的区别和用法。 ... [详细]
  • 给定一个二维平面上的一些点,通过计算曼哈顿距离,求连接所有点的最小总费用。只有任意两点之间有且仅有一条简单路径时,才认为所有点都已连接。给出了几个示例并给出了对应的输出。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 判断数组是否全为0_连续子数组的最大和的解题思路及代码方法一_动态规划
    本文介绍了判断数组是否全为0以及求解连续子数组的最大和的解题思路及代码方法一,即动态规划。通过动态规划的方法,可以找出连续子数组的最大和,具体思路是尽量选择正数的部分,遇到负数则不选择进去,遇到正数则保留并继续考察。本文给出了状态定义和状态转移方程,并提供了具体的代码实现。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了Java数组的定义、初始化和多维数组的用法。通过动态初始化和静态初始化两种方式来初始化数组,并讨论了数组的内存分配和下标的特点。同时详细介绍了Java二维数组的概念和使用方法。 ... [详细]
author-avatar
fangsi155_7827d9
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有