LeetCode73-矩阵置零

LeetCode73-矩阵置零

给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 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]
]

进阶:

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

一、思路

这里,我们只讨论空间复杂度为常数的算法。

题目的要求很简单,但是隐藏了一些信息,假设矩阵中,有个0位于 ( i , j ) (i,j) (i,j)处,那么我们可以知道最终变换后的矩阵,第 i i i行、第 j j j列全部为0,于是有:

m a t r i x [ i ] [ 0 ] = 0 matrix[i][0]=0 matrix[i][0]=0

m a t r i x [ 0 ] [ j ] = 0 matrix[0][j]=0 matrix[0][j]=0

我们不能在找到这个0之后,马上对第 i i i行、第 j j j列进行赋值,是因为,接下来,我们需要遍历第 i + 1 i+1 i+1行(如果是按列遍历,就是第 j + 1 j+1 j+1列),如果你进行了置0的操作,那么可能会将原来第 i + 1 i+1 i+1行不是0的数变成了0,然后这个0也会被认为是原来矩阵中的0,如此一来就会出错

现在为了解决这个问题,我们对矩阵进行了划分:
在这里插入图片描述
这里,我们将第1行与第1列单独拿出来作为标志行与标志列,这对应于上图中蓝色的部分

这里,我们先对标致行与标志列进行遍历,看看有没有0,如果有则将对应的flag标志置为true,表示该标志行(列)需要在最后一步中全部置0。

然后对剩下的那个小矩阵进行遍历,每当找到0的时候,就将对应的标志行与标志列的值置为0:
在这里插入图片描述
当遍历完整个小矩阵后,标志行与标志列的填写就完成了,此时再次遍历小矩阵,将标致行中为0的那一列全部置0,标志列中为0的那一行全部置为0

最后处理标志行与标志列,根据对应的flag来确定是否需要置零

C++代码:

class Solution {
public:
	void setZeroes(vector<vector<int>>& matrix) {
		if (matrix.empty() || matrix[0].empty())
			return;
		// 使用第0行、第0列的对应位置来存放0,表示该行/列全部为0
		bool col0_is_zeros = false, row0_is_zeros = false;
		// 先遍历一遍第0行、第0列,看看里面有没有0
		for (int i = 0; i < matrix.size(); i++)
			if (matrix[i][0] == 0) {
				col0_is_zeros = true;
				break;
			}
		for (int j = 0; j < matrix[0].size(); j++)
			if (matrix[0][j] == 0) {
				row0_is_zeros = true;
				break;
			}
		// 遍历除第0行、第0列的矩阵,查找哪些行、列出现过0,并将对应的行、列的第一个数字提前置零,作为标志
		for (int i = 1; i < matrix.size(); i++)
			for (int j = 1; j < matrix[i].size(); j++)
				if (matrix[i][j] == 0) {
					matrix[i][0] = 0;
					matrix[0][j] = 0;
				}
		// 遍历除第0行、第0列的矩阵,赋值0
		for (int i = 1; i < matrix.size(); i++)
			for (int j = 1; j < matrix[i].size(); j++)
				if (matrix[i][0] == 0 || matrix[0][j] == 0)
					matrix[i][j] = 0;
		// 第0行、第0列是否为0
		if (row0_is_zeros) 
			for (int j = 0; j < matrix[0].size(); j++)
				matrix[0][j] = 0;
		if (col0_is_zeros)
			for (int i = 0; i < matrix.size(); i++)
				matrix[i][0] = 0;
		return;
	}
};

执行效率:
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值