【力扣 73】矩阵置零 C++题解(向量+位集合+循环+矩阵)

64 阅读1分钟

给定一个 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