给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 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 -231 <= matrix[i][j] <= 231 - 1
进阶:
一个直观的解决方案是使用 O(mn) 的额外空间,但这并不是一个好的解决方案。 一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。 你能想出一个仅使用常量空间的解决方案吗?
思路
通过两次遍历来实现目标。首先,遍历矩阵中的每一行,如果在某一行中发现了元素0,就使用bitset数据结构zc记录下这个元素所在的列,并将这一行的所有元素都置为0。这样,第一次遍历结束后,所有包含0的行都已经被置为0,而所有包含0的列都被记录在zc中。
然后,在第二次遍历中,算法会遍历矩阵中的每一个元素,如果这个元素所在的列在zc中被记录过,就将这个元素置为0。这样,第二次遍历结束后,所有包含0的列也都被置为0。
AC代码
/*
* @lc app=leetcode.cn id=73 lang=cpp
*
* [73] 矩阵置零
*/
// @lc code=start
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
const int m = matrix.size();
const int n = matrix[0].size();
bitset<200> zc;
zc.reset();
for (int i = 0; i < m; i++) {
bool flg = 0;
for (int j = 0; j < n; j++) {
if (!matrix[i][j]) {
zc.set(j);
flg = 1;
}
}
if (flg) {
for (int j = 0; j < n; j++) {
matrix[i][j] = 0;
}
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (zc[j]) {
matrix[i][j] = 0;
}
}
}
}
};
// @lc code=end