一、题目
二、分析
- 可以采用两个集合,分别记录某一行/某一列是否存在0元素。这种比直接设置两个数组要优化一丢丢。
[[1,1,1],
[1,0,1],
[1,1,1]]
set<int> rowzero; // {1},第1行有0
set<int> colzero; // {1},第1列有0
这种情况最坏的空间复杂度还是 O ( m + n ) O(m+n) O(m+n)。
- 如果第一行和第一列都没有0,如上边例子,那可以用第一行和第一列记录该列或该行有没有0。
注
:要另外记录第一行和第一列有没有0。
1,1,2,3
3,4,0,2
1,0,1,5
--------
1,0,0,3
0,4,0,2
0,0,1,5
用第一行和第一列记录是否有0。
以第二行为例,整个第二行都会被置0,那使用开头的第二行第一列元素来记录完全不会影响它的值。
三、代码
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
int m(matrix.size()), n(matrix[0].size());
set<int> rowzero;
set<int> colzero;
for(int i = 0; i < m; i ++){
for(int j = 0 ; j < n ; j++){
if(matrix[i][j] == 0){
rowzero.insert(i);
colzero.insert(j);
}
}
}
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(rowzero.find(i) != rowzero.end()|| colzero.find(j) != colzero.end()){
matrix[i][j] = 0;
}
}
}
}
};
执行用时:12 ms, 在所有 C++ 提交中击败了94.77%的用户
内存消耗:13.2 MB, 在所有 C++ 提交中击败了27.88%的用户
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
int m(matrix.size()), n(matrix[0].size());
bool firstrow_zero = false;
bool firstcol_zero = false;
//第一列是否有0
for(int i = 0; i < m; i ++){
if(matrix[i][0] == 0){
firstcol_zero = true;
break;
}
}
//第一行是否有0
for(int j = 0 ; j < n ; j++){
if(matrix[0][j] == 0){
firstrow_zero = true;
break;
}
}
//用第一行和第一列记录0元素
for(int i = 1; i < m; i++){
for(int j = 1; j < n; j++){
if(matrix[i][j] == 0){
matrix[i][0] = 0;
matrix[0][j] = 0;
}
}
}
//置0操作
for(int i = 1; i < m; i++){
for(int j = 1; j < n; j++){
if(matrix[0][j] == 0 || matrix[i][0] == 0){
matrix[i][j] = 0;
}
}
}
//勿忘第一行和列
if(firstcol_zero){
for(int i = 0; i < m; i ++){
matrix[i][0] = 0;
}
}
if(firstrow_zero){
for(int j = 0 ; j < n ; j++){
matrix[0][j] = 0;
}
}
}
};
执行用时:16 ms, 在所有 C++ 提交中击败了80.35%的用户
内存消耗:12.9 MB, 在所有 C++ 提交中击败了75.56%的用户