难度中等
给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法。
目标:使用 O(m + n) 的额外空间
思路:
遍历全部点,使用两个 set 分别保存应该置零的行号和列号
void setZeroes(vector<vector<int>>& matrix) {
unordered_set<int> rows,cols;
for(int i=0;i<matrix.size();++i){
for(int j=0;j<matrix[0].size();++j){
if(!matrix[i][j]){
rows.insert(i);
cols.insert(j);
}
}
}
for(auto col:cols){
for(int i=0;i<matrix.size();++i){
matrix[i][col]=0;
}
}
for(auto row:rows){ // 迭代器已经屏蔽了矩阵中不存在内容的情况
for(int j=0;j<matrix[0].size();++j){
matrix[row][j]=0;
}
}
}
目标:使用 O(m + n) 的额外空间
思路:
根据若某点为零,将分别将改行和该列的第一个元素置零,再根据首行和首列的零情况将整行或者整列置零。
第一个位置需要单独考虑(第一行和第一列的置零会重复),设置一个标志位单独表示第一行,第一个位置信息表示第一列
void setZeroes(vector<vector<int>>& matrix) {
// 边界指定法 // [0][0]可能会重复,因此单独讨论
if(!matrix.size()) return;
bool isTrue=false;
for(int i=0;i<matrix.size();++i){
if(!matrix[i][0]) isTrue=true;
for(int j=1;j<matrix[0].size();++j){
if(!matrix[i][j]){
matrix[i][0]=0;
matrix[0][j]=0;
}
}
}
for(int i=1;i<matrix.size();++i){
for(int j=1;j<matrix[0].size();++j){
if(!matrix[i][0] || !matrix[0][j]){
matrix[i][j]=0;
}
}
}
if(!matrix[0][0]){
for(int i=0;i<matrix[0].size();++i){
matrix[0][i]=0;
}
}
if(isTrue){
for(int i=0;i<matrix.size();++i){
matrix[i][0]=0;
}
}
}