1. 题目介绍
2. 思路
本题的难点在于要使用原地修改的方式来处理矩阵,一般会想到原地打标记的方式来处理矩阵,但是处理过程中,将矩阵中的原数置处理,可能会影响接下来的遍历。
2.1 使用hash方式来打标记
这是我自己想到的一种方式,因为考虑到不能开辟一个新的空间来记录标记,那么,直接将数组中的数据改成一个特殊值那最好。
算法流程:
- 遍历整个数组,如果有数据为0,则将其保存的值改为计算的hash值。
- 再次整个数组,如果该位置的数据和hash值相等,则修改该处对应行和对应列的所有非hash值的数据为0(因为直接列和行的数据全改成0,可能会丢掉同样行/列的原来值为0的标记)
- 再次遍历整个数组,将所有打上标记的hash值改成0
class Solution {
public:
// 自定义的一个hash函数,不是很好,但这里足够用
int myHash(long long x, long long y) {
return (100007 + x * x + y * y) % 1000000000007;
}
void setZeroes(vector<vector<int>>& matrix) {
int m = matrix.size();
int n = matrix[0].size();
// 1.第一次遍历整个矩阵,对于0值,打上标记
for(int i = 0; i < m; ++i) {
for(int j = 0; j < n; ++j) {
if(matrix[i][j] == 0) {
matrix[i][j] = myHash(i, j);
}
}
}
// 2.再次遍历矩阵,对于已有标记,将对应行/列的非标记数据置为0
for(int i = 0; i < m; ++i) {
for(int j =0; j < n; ++j) {
if(matrix[i][j] == myHash(i, j)) {
for(int di = 0; di < m; ++di) {
if(matrix[di][j] != myHash(di, j)) {
matrix[di][j] = 0;
}
}
for(int dj = 0; dj < n; ++dj) {
if(matrix[i][dj] != myHash(i, dj)) {
matrix[i][dj] = 0;
}
}
}
}
}
// 3. 遍历整个矩阵,将原来打上标记的值置为0
for(int i = 0; i < m; ++i) {
for(int j = 0; j < n; ++j) {
if(matrix[i][j] == myHash(i, j)) {
matrix[i][j] = 0;
}
}
}
}
};
2.2 利用第一行和第一列来标记
这个也是官方题解的第二种方法。
leetcode.cn/problems/se…
可以利用第一行来记录所有需要置0的列,用第一列来记录所有需要置0的行。那么需要怎么处理原来第一行/列有0的情况?
这里有个小细节需要我们发现到,一旦第一行有0,则该行整行都需要置为0,同理,第一列有0,则整列都需要置0,因此我们可以提前先记录第一行/列的0情况,最后处理。
算法流程:
- 记录第一行和第一列的0情况,用两个flag保存
- 遍历整个矩阵,如果有0,则将对应列第一行,以及对应行第一列打上标记(置为0)
- 根据第一行的标记,将对应列的所有数据置为0,同理,根据第一列情况将行置0
- 最后,按照1中记录的flag,将第一行/列整个置0
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
int m = matrix.size();
int n = matrix[0].size();
// 记录第一行和第一列的0的情况
int zero_row0 = false;
int zero_col0 = false;
for(int i = 0; i < m; ++i) {
if(matrix[i][0] == 0) {
zero_col0 = true;
}
}
for(int j = 0; j < n; ++j) {
if(matrix[0][j] == 0) {
zero_row0 = true;
}
}
// 遍历整个矩阵,在第一行/列打标记
for(int i = 1; i < m; ++i) {
for(int j = 1; j < n; ++j) {
if(matrix[i][j] == 0) {
matrix[0][j] = 0;
matrix[i][0] = 0;
}
}
}
// 根据第一行/列的标记情况,置0
for(int i = 1; i < m; ++i) {
if(matrix[i][0] == 0) {
for(int j = 1; j < n; ++j) {
matrix[i][j] = 0;
}
}
}
for(int j = 1; j < n; ++j) {
if(matrix[0][j] == 0) {
for(int i = 1; i < m; ++i) {
matrix[i][j] = 0;
}
}
}
// 最后处理,第一行/列的情况,整行/列置0
if(zero_row0) {
for(int j = 0; j < n; ++j) {
matrix[0][j] = 0;
}
}
if(zero_col0) {
for(int i = 0; i < m; ++i) {
matrix[i][0] = 0;
}
}
}
};