【LeetCode】73. Set Matrix Zeroes 解题报告(Python & C++)
作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/
题目地址:https://leetcode.com/problems/set-matrix-zeroes/description/
题目描述
Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in-place.
Example 1:
Input:
[
[1,1,1],
[1,0,1],
[1,1,1]
]
Output:
[
[1,0,1],
[0,0,0],
[1,0,1]
]
Example 2:
Input:
[
[0,1,2,0],
[3,4,5,2],
[1,3,1,5]
]
Output:
[
[0,0,0,0],
[0,4,5,0],
[0,3,1,0]
]
Follow up:
- A straight forward solution using O(mn) space is probably a bad idea.
- A simple improvement uses O(m + n) space, but still not the best solution.
- Could you devise a constant space solution?
题目大意
有一个二维矩阵,如果某一个位置出现了0,那么这个0所在的行和列全部转化成0. 原地操作。
解题方法
原地操作
最简单的方法就是用一个新的二维矩阵保存每个位置的结果,最后再放回原地了,题目说了这样不好。
一个简单的优化是,只需要保存每行和每列是否应该置为0,这样用了O(m+n)的空间,但是还有更好的解法。
我想了一个不用额外空间的,暴力的解法。时间上也勉强通过了。。
这个题和289. Game of Life比较像,289题只用判断8-连通,而这个题需要判断一整行。
我使用的方法是将每个位置的元素的二进制再增加一位,也就是说在末尾补上一个0或者1代表这个是否应该变成0或者不变。如果经过遍历之后,发现最后一位是0,那么把这个位置的数字变成0,如果最后一位是1,那么把这个位置的数字还原成原来的数字(右移一位)。
由于每个数字记录它的状态是在原地进行的,所以我说没有用到额外的空间。但这个题不好的地方在于,第一,没有说出MN的范围,让我很难判断这个解法能否通过;第二,没有说出matrix[m][n]的范围,不能判断左移一位之后,整数是否溢出(Python不存在这个问题)。
时间复杂度是O((M*N) * (M + N)),空间复杂度是O(1).
时间复杂度有(M + N)是因为,对于每个位置都去把这个行、列的所有数值进行了遍历来判断是否存在0,其实可以通过把结果保存到这个行列的第一个位置即可,降低了判断的时间复杂度。
代码如下:
class Solution(object):
def setZeroes(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: void Do not return anything, modify matrix in-place instead.
"""
M, N = len(matrix), len(matrix[0])
# (old + new)
if matrix and matrix[0]:
for m in range(M):
for n in range(N):
matrix[m][n] = (matrix[m][n] << 1) + (1 if matrix[m][n] else 0)
for m in range(M):
for n in range(N):
if self.getPos(matrix, m, n) == 0:
matrix[m][n] = matrix[m][n] >> 1 << 1
for m in range(M):
for n in range(N):
if matrix[m][n] & 1 == 0:
matrix[m][n] = 0
else:
matrix[m][n] >>= 1
def getPos(self, matrix, m, n):
# return 0 means this place ==> 0; 1 ==> don't change
if matrix[m][n] == 0:
return 0
M, N = len(matrix), len(matrix[0])
if any((matrix[m][i] >> 1) == 0 for i in range(N)):
return 0
if any((matrix[i][n] >> 1) == 0 for i in range(M)):
return 0
return 1
这个解法本身是有问题的,如果左移超出INT最大值的时候。比如C++这个方法就过不了。测试用例果然有个INT最大值,这样左移就超出范围了,下面解法是错的。
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
if (matrix.size() == 0 || matrix[0].size() == 0) return;
const int M = matrix.size(), N = matrix[0].size();
for (int i = 0; i < M; ++i) {
for (int j = 0; j < N; ++j) {
if (matrix[i][j] != 0)
matrix[i][j] = 1 + (matrix[i][j] << 1);
}
}
for (int r = 0; r < M; ++r) {
for (int c = 0; c < N; ++c) {
if (matrix[r][c] == 0) {
for (int j = 0; j < N; ++j) {
matrix[r][j] >>= 1;
matrix[r][j] <<= 1;
}
for (int i = 0; i < M; ++i) {
matrix[i][c] >>= 1;
matrix[i][c] <<= 1;
}
}
}
}
for (int i = 0; i < M; ++i) {
for (int j = 0; j < N; ++j) {
if ((matrix[i][j] & 1) == 1) {
matrix[i][j] >>= 1;
} else {
matrix[i][j] = 0;
}
}
}
}
};
新建数组
如果使用新的数组,把老数组拷贝一份,那么就可以在原数组上进行判断,在新数组上进行修改,也就是题目说的O(MN)的空间复杂度。
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
if (matrix.size() == 0 || matrix[0].size() == 0) return;
vector<vector<int>> newM(matrix);
const int M = matrix.size(), N = matrix[0].size();
for (int r = 0; r < M; ++r) {
for (int c = 0; c < N; ++c) {
if (newM[r][c] == 0) {
for (int j = 0; j < N; ++j) {
matrix[r][j] = 0;
}
for (int i = 0; i < M; ++i) {
matrix[i][c] = 0;
}
}
}
}
}
};
队列
使用一个队列保存出现过0的位置,然后就可以再次遍历把所有的位置设置为0了。这里也可以使用其他的数据结构。
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
if (matrix.size() == 0 || matrix[0].size() == 0) return;
const int M = matrix.size(), N = matrix[0].size();
queue<pair<int, int>> q;
for (int r = 0; r < M; ++r) {
for (int c = 0; c < N; ++c) {
if (matrix[r][c] == 0) {
q.push({r, c});
}
}
}
while (!q.empty()) {
auto p = q.front(); q.pop();
for (int j = 0; j < N; ++j) {
matrix[p.first][j] = 0;
}
for (int i = 0; i < M; ++i) {
matrix[i][p.second] = 0;
}
}
}
};
参考资料:
日期
2018 年 9 月 26 日 —— 美好的一周又快要过去了。。
2018 年 12 月 17 日 —— 周一要从早起开始
【LeetCode】73. Set Matrix Zeroes 解题报告(Python & C++)的更多相关文章
- [LeetCode] 73. Set Matrix Zeroes 解题思路
Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. Follow ...
- 【LeetCode】Set Matrix Zeroes 解题报告
今天看到CSDN博客的勋章换了图表,同一时候也添加显示了博客等级,看起来都听清新的,感觉不错! [题目] Given a m x n matrix, if an element is 0, set i ...
- LeetCode: Set Matrix Zeroes 解题报告
Set Matrix ZeroesGiven a m x n matrix, if an element is 0, set its entire row and column to 0. Do it ...
- 【LeetCode】283. Move Zeroes 解题报告(Java & Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:首尾指针 方法二:头部双指针+双循环 方法三 ...
- [LeetCode] 73. Set Matrix Zeroes 矩阵赋零
Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in-place. Exampl ...
- leetcode[73] Set Matrix Zeroes 将矩阵置零
给定一个矩阵,把零值所在的行和列都置为零.例如: 1 2 3 1 3 1 1 1 操作之后变为 1 3 0 0 0 1 1 方法1: 赋值另存一个m*n的矩阵,在原矩阵为零的值相应置新的矩阵行和列为零 ...
- 【LeetCode】62. Unique Paths 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址:https://leetcode.com/problems/unique-pa ...
- Leetcode#73 Set Matrix Zeroes
原题地址 用矩形的第一行和第一列充当mask 代码: void setZeroes(vector<vector<int> > &matrix) { ].empty()) ...
- 【LeetCode】474. Ones and Zeroes 解题报告(Python)
[LeetCode]474. Ones and Zeroes 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ ...
随机推荐
- excel-合并多个Excel文件--VBA合并当前目录下所有Excel工作簿中的所有工作表
在网上找EXCEL多文件合并的方法,思路: 一.Linux 或者window+cmder,直接用命令行cat合并EXCEL文件,但是,需要安装辅助东西才能直接处理(也许也不可以,但是,可以用文件格式转 ...
- 用C语言的LED实验,有汇编哦!
C语言LED实验 1.汇编激活CPU 首先要明白对于没有系统开发板(也就是裸机)来说,是没办法直接对C进行识别.所以需要一段汇编语言,来配置CPU的资源,选择CPU运行模式,初始化指针位置. 代码如下 ...
- 在Kubernetes上安装Percona XtraDB集群
官方文档地址:https://www.percona.com/doc/kubernetes-operator-for-pxc/kubernetes.html 一.简介 Percona XtraDB C ...
- 如何使用 Kind 快速创建 K8s 集群?
作者|段超 来源|尔达 Erda 公众号 导读:Erda 作为一站式云原生 PaaS 平台,现已面向广大开发者完成 70w+ 核心代码全部开源!在 Erda 开源的同时,我们计划编写<基于 ...
- set、multiset深度探索
set/multiset的底层是rb_tree,因此它有自动排序特性.set中的元素不允许重复必须独一无二,key与value值相同,multiset中的元素允许重复. set的模板参数key即为关键 ...
- Android 开源框架Universal-Image-Loader加载https图片
解决方案就是 需要 android https HttpsURLConnection 这个类忽略证书 1,找到 Universal-Image-Loader的library依赖包下面com.nostr ...
- API测试最佳实践 - 身份验证
适用等级:高级 1. 概况 身份验证通常被定义为是对某个资源的身份的确认的活动,这里面资源的身份指代的是API的消费者(或者说是调用者).一旦一个用户的身份验证通过了,他将被授权访问那些期待访问的资源 ...
- 锁对象-条件对象-synchronized关键字
1 import java.util.concurrent.locks.Condition; 2 import java.util.concurrent.locks.Lock; 3 import ja ...
- size_type 和 size_t 的区别
标准库string里面有个函数size,用来返回字符串中的字符个数,具体用法如下:string st("The expense of spirit\n");cout << ...
- JFinal之ActiveRecord开发示例
JFinal独创Db + Record模式示例 JFinal配备的ActiveRecord插件,除了实现了类似Rails ActiveRecrod的功能之外,还实现了Db + Record模式,此模式 ...