地址:https://leetcode.com/problems/set-matrix-zeroes/
题目:
Given a
m
m
m x
n
n
n matrix, if an element is 0, set its entire row and column to 0. Do it in-place.
Example 1:
Example 2:
Follow up:
- A straight forward solution using O ( m n ) O(mn) O(mn) space is probably a bad idea.
- A simple improvement uses O ( m + n ) O(m + n) O(m+n) space, but still not the best solution.
- Could you devise a constant space solution?
理解:
就是如果原数组的某个位置是0,把其所在行列都置为0
straight forward的想法就是用一个新数组喽,复杂度是
O
(
m
n
)
O(mn)
O(mn)。
这个题麻烦的地方是如果某个元素是0,把行列都置为0会影响后面的判断,因此可以把需要置0的位置存成一个和所有数都不相同的数,这样就不会混淆了。但是这样的时间复杂度很高。
实现1:
O
(
m
+
n
)
O(m+n)
O(m+n)的思路就是记录下应该是0的行和列,最后再赋值一次。
不过这里用unordered_set
好像很慢的样子,可以用数组
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
unordered_set<int> rs, cs;
for (int i = 0; i < matrix.size(); ++i) {
for (int j = 0; j < matrix[0].size(); ++j) {
if (matrix[i][j] == 0) {
rs.insert(i);
cs.insert(j);
}
}
}
for (auto i : rs) {
for (int j = 0; j < matrix[0].size(); ++j)
matrix[i][j] = 0;
}
for (auto j : cs) {
for (int i = 0; i < matrix.size(); ++i)
matrix[i][j] = 0;
}
}
};
实现2:
如果要求空间复杂度为
O
(
1
)
O(1)
O(1)的话,可以借第一行和第一列来表示是否应该把该行或者该列置为0。对于matrix[i][j]
可以用matrix[0][j]和matrix[i][0]来表示。注意到对于matrix[0][0],两个位置是重合的,因此需要一个额外的空间来表示。也就是matrix[0][0]表示的是第0行应该置为0,firstCol表示第0列应该置为0。
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
bool firstCol=false;
int r=matrix.size(),c=matrix[0].size();
for(int i=0;i<r;++i){
if(matrix[i][0]==0)
firstCol=true;
for(int j=1;j<c;++j){
if(matrix[i][j]==0){
matrix[i][0]=0;
matrix[0][j]=0;
}
}
}
for(int i=1;i<r;++i){
for(int j=1;j<c;++j){
if(matrix[i][0]==0||matrix[0][j]==0)
matrix[i][j]=0;
}
}
if(matrix[0][0]==0)
for(int j=1;j<c;++j)
matrix[0][j]=0;
if(firstCol)
for(int i=0;i<r;++i)
matrix[i][0]=0;
}
};