思路:
1.用额外的额数组或者哈希表来记录矩阵元素为0的位置
2.在原地实现记录,那就要用本来矩阵的空间作为记录数组。我们选用第一行和第一列来记录其他行列的元素情况。因为如果一个元素为0,则它所在行列都置为0,所以我们只需要记录一个元素的第一行和第一列标记,就可以实现:
(比如位置[i][j],只需要将[i][0]和[0][j]置0标记,这样对于第i行和第j列的元素,只要通过该元素的第0行和第0列的标记就可以判断是否应该置0)。
我们先通过行列标记将其余行列元素置0,最后根据是否第一行列有0元素来将第一行列元素置0,这样不会影响到其他元素的置0判断条件。
原题链接:https://leetcode.cn/problems/set-matrix-zeroes/description/?favorite=2ckc81c
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)
的额外空间,但这仍然不是最好的解决方案。 你能想出一个仅使用常量空间的解决方案吗?
2.代码如下:
class Solution {
public:
//思路一:使用集合来存储元素0所在的行列坐标,需要额外空间
//思路二:使用mark矩阵来标记0元素
//思路三:要在原地实现 用矩阵的自带空间实现记录
/*
首先用变量记录第一行和第一列是否有0元素;
再用第一行和第一列的数组来记录其他行列是否有0元素
*/
void setZeroes(vector<vector<int>>& matrix) {
int m=matrix.size();
int n=matrix[0].size();
//变量记录第一行和第一列的情况,这里是为最后对第一行和第一列置0
int flag_col0=false,flag_row0=false;
for (int i=0;i<m;i++) {
if (!matrix[i][0]) {
flag_col0=true;
}
}
for (int j=0;j<n;j++) {
if (!matrix[0][j]) {
flag_row0=true;
}
}
for (int i=1;i<m;i++) {
for (int j=1;j<n;j++) {
if (!matrix[i][j]) {
// 用第一列和第一行作为记录数值,通过矩阵的性质来定位为0的元素位置
matrix[i][0]=matrix[0][j] = 0;
}
}
}
//通过第一行和第一列的标记,只要该位置所在的第一行or第一列标记是0的,就将元素置为0
for (int i=1;i<m;i++) {
for (int j=1;j<n;j++) {
if (!matrix[i][0] || !matrix[0][j]) {
matrix[i][j]=0;
}
}
}
// 对第一行和第一列处理,如果第一列or第一行有0元素,则第一行or第一列全置为0,
// 最后对第一列第一行处理不会影响到其他列的情况,同时原本第一列和第一行为0的标记也会作为其他位置元素置0的条件
if(flag_col0) {
for (int i=0;i<m;i++) {
matrix[i][0]=0;
}
}
if(flag_row0) {
for (int j=0;j<n;j++) {
matrix[0][j]=0;
}
}
}
};