【程序员面试金典】01.08.零矩阵
admin
2024-01-17 12:35:12
0

零矩阵

编写一种算法,若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]
]

题目解法

解法 1

乍一看,这个问题似乎显而易见,直接遍历整个矩阵,只要发现值为0的元素,就将其所在的行和列清零。不过这种方法存在陷阱:在读取被清零的行或列时,读到的都是0,于是所在行和列都会变成0,很快,整个矩阵的所有元素都会变成0。

避开这个陷阱的方法之一是,新建一个矩阵,标记0元素位置,然后,在第二次遍历矩阵时,将0所在的行与列清零。这种做法的空间复杂度为O(MN)。

实际,不需要用矩阵存储,只需要用两个数组分别记录包含0元素的行和列即可,空间复杂度为O(N)。

算法实现(JAVA)

public class Solution {public void setZeroes(int[][] matrix) {boolean[] row = new boolean[matrix.length];boolean[] col = new boolean[matrix[0].length];for (int i = 0; i < matrix.length; i++) {for (int j = 0; j < matrix[0].length; j++) {if (matrix[i][j] == 0) {row[i] = true;col[j] = true;}}}// 置空行for (int i = 0; i < matrix.length; i++) {if (row[i]) {nullifyRow( matrix, i);}}// 置空列for (int j = 0; j < matrix[0].length; j++) {if (col[j]) {nullifyCol(matrix, j);}}}private void nullifyRow(int[][] matrix, int row) {for (int j = 0; j < matrix[0].length; j++) {matrix[row][j] = 0;}}private void nullifyCol(int[][] matrix, int col) {for (int i = 0; i < matrix.length; i++) {matrix[i][col] = 0;}}
}

解法 2

为了提高空间利用率,可以选用位向量替代布尔数组。通过使用矩阵的第一行代替解法1中的row数组,矩阵的第一列代替col数组,可以将算法的空间复杂度降为O(1),具体步骤如下。

  1. 检查第一行和第一列是否存在0元素,并根据结果设置rowHasZero和colHasZero的值。
  2. 遍历矩阵其余元素,如果matrix[i][j]为0,则将matrix[i][0]和matrix[0][j]置为0。
  3. 遍历矩阵中的其余元素,如果matrix[i][0]为0,则将第i行清零。
  4. 遍历矩阵中的其余元素,如果matrix[0][j]为0,则将第j行清零。
  5. 根据第1步的结果,如果需要则将第一行和第一列清零。

算法实现(JAVA)

public class Solution2 {public void setZeroes(int[][] matrix) {boolean rowHasZero = false;boolean colHasZero = false;// 检查第一行是否有0for (int j = 0; j < matrix[0].length; j++) {if (matrix[0][j] == 0) {rowHasZero = true;break;}}// 检查第一列是否有0for (int i = 0; i < matrix.length; i++) {if (matrix[i][0] == 0) {colHasZero = true;break;}}// 检查数组其余元素是否有0for (int i = 1; i < matrix.length; i++) {for (int j = 1; j < matrix[0].length; j++) {if (matrix[i][j] == 0) {matrix[i][0] = 0;matrix[0][j] = 0;}}}// 根据第一列的值置空行for (int i = 1; i < matrix.length; i++) {if (matrix[i][0] == 0) {nullifyRow(i, matrix);}}// 根据第一行的值置空列for (int j = 1; j < matrix[0].length; j++) {if (matrix[0][j] == 0) {nullifyCol(j, matrix);}}// 置空第一行if (rowHasZero) {nullifyRow(0, matrix);}// 置空第一列if (colHasZero) {nullifyCol(0, matrix);}}private void nullifyRow(int row, int[][] matrix) {for (int j = 0; j < matrix[0].length; j++) {matrix[row][j] = 0;}}private void nullifyCol(int col, int[][] matrix) {for (int i = 0; i < matrix.length; i++) {matrix[i][col] = 0;}}
}

[1] 盖尔.拉克曼.麦克道尔.程序员面试金典(第6版)[M].北京:人民邮电出版社,2019.9:167-169
[2] leetcode.面试题 01.08. 零矩阵

相关内容

热门资讯

小鹏汽车在长春成立销售服务公司... 天眼查工商信息显示,近日,长春小鹏汽车销售服务有限公司成立,法定代表人为陈志远,注册资本500万人民...
商务部:对原产于美国和韩国的进... 商务部公告2026年第3号 公布对原产于美国和韩国的进口太阳能级多晶硅所适用反倾销措施的期终复审裁定...
“A系列”指数回调,关注A50... 截至收盘,中证A500指数下跌0.8%,中证A100指数下跌0.6%,中证A50指数下跌0.4%。 ...
港股上市!国改发展基金基石投资... 1月12日,宁波通商基金通过市国资国企改革发展基金之甬欣基金参与基石投资的豪威集成电路(集团)股份有...
穆迪:未来五年数据中心投资或达... 据彭博社等外媒报道,国际三大信用评级机构之一穆迪近日发布报告称,未来五年内,全球至少将有3万亿美元资...
人民币现金收付新规来了 注意! 2026年2月1日起 人民币现金收付新规正式实施 遇拒收现金可维权 日前,中国人民银行会同...
海底捞CEO换人 1月13日,海底捞国际控股有限公司(以下简称“海底捞”)在港交所发布公告,宣布该公司董事会主席及执行...
估值腰斩、家族掌舵、三次递表,... 近日,中式快餐品牌“老乡鸡”的控股公司——于开曼群岛注册的LXJ International Hol...
数字人短视频怎么做?一文搞懂 随着AI技术普及,数字人短视频已成内容创作新风口。不少创作者和企业想借此降本增效,却受困于核心准备、...
盼盼食品董事长蔡金垵入选“20... 瑞财经 1月13日,由瑞财经推出的“2025年度食品行业十大杰出人物”榜单揭晓,盼盼食品董事长蔡金垵...
威海营商行丨出口“秒通关”,海... 1月8日,在威海青正蓝海食品有限公司生产车间,经过清洗、调味、包装、冷冻等加工工序,一批近20吨的调...
凯德北京投资基金管理有限公司:... 穆迪最新发布的报告预测,在人工智能与云计算浪潮的强力驱动下,未来五年内,全球投向数据中心相关领域的资...
创维创始人黄宏生:全面拥抱AI... 近日,创维集团&开沃集团创始人黄宏生接受南都湾财社记者等媒体采访,黄宏生表示,2025年创维光伏的业...
北交所上市公司众诚科技登龙虎榜... 每经讯,2026年1月13日,北交所上市公司众诚科技(920207,收盘价:42.37元)登上龙虎榜...
原创 果... 前言 2026年初,美军三角洲部队发动了一场突袭,将委内瑞拉总统马杜罗捉拿,显然是打算复制中东的成功...
焦点复盘科创50低开低走跌近3... 财联社1月13日讯,今日66股涨停,61股炸板,封板率为52%,锋龙股份13连板,鲁信创投13天11...
原创 不... 2026年1月,美军突袭委内瑞拉,并迅速掌控了该国事务,其核心目标直指全球最大石油储量。虽然美国自身...
2025融资性信保业务“踩刹车... 作者 |风翎 编辑 | 付影 来源 | 独角金融 2025年,中国融资性信用保险行业迎来前所未有的“...
千味央厨今日大宗交易成交137... 1月13日,千味央厨大宗交易成交137.8万股,成交额5726.45万元,占当日总成交额的27.23...