思路一: space complexity为O(m+n),虽然题目要求O(1),但是我一开始只能想到这个方法,所以还是实现了一下。Anyway, it’s not too bad。将复杂度控制在m+n是因为用了set。set里存放需要置0的行和列。思路很简单,直接展示代码:
class Solution {
public void setZeroes(int[][] matrix) {
int m = matrix.length;
int n = matrix[0].length;
Set<Integer> row = new HashSet<>();
Set<Integer> col = new HashSet<>();
for(int i = 0; i < m ; i++){
for(int j = 0; j < n; j++){
if(matrix[i][j] == 0){
row.add(i);
}
}
}
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
if(matrix[j][i] == 0){
col.add(i);
}
}
}
for(Integer i : row){
for(int k = 0; k < n; k++){matrix[i][k] = 0;}
}
for(Integer i : col){
for(int k = 0; k < m; k++){matrix[k][i] = 0;}
}
}
}
思路二: time complexity O(1)。其实这个方法在我思考的时候曾经从脑子里闪过,但是很可惜我没有深究。基本想法是先遍历整个matrix,碰到0,就把该元素所在的行与列的第一个元素置0(每一行和每一列的第一个元素相当于一个flag,标记着这一行(列)是否需要置0)。但是这边有两个special cases,第一行和第一列需要单独考虑。因为matrix[0][0]不仅仅代表第一行,还代表第一列。如果matrix[0][0]为0,我们无法确定到底是要将第一行置0还是将第一列置0还是将第一行和第一列都置0。下面展示代码:
class Solution {
public void setZeroes(int[][] matrix) {
int m = matrix.length;
int n = matrix[0].length;
int judgeRow = 0;
int judgeCol = 0;
// 判断第一行和第一列有没有0
for(int i = 0; i < n; i++){
if(matrix[0][i] == 0) judgeRow = 1;
}
for(int i = 0; i < m; i++){
if(matrix[i][0] == 0) judgeCol = 1;
}
// 标记哪些行和哪些列需要置0
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(matrix[i][j] == 0){
matrix[i][0] = 0;
matrix[0][j] = 0;
}
}
}
// 从第二行开始,置0操作,留下第一行待会单独考虑
for(int i = 1; i < m; i++){
if(matrix[i][0] == 0){
for(int j = 0; j < n; j++){
matrix[i][j] = 0;
}
}
}
// 从第二列开始,置0操作,留下第一列待会单独考虑
for(int i = 1; i < n; i++){
if(matrix[0][i] == 0){
for(int j = 0; j < m; j++){
matrix[j][i] = 0;
}
}
}
// 第一行与第一列单独考虑
if(judgeCol == 1){
for(int i = 0; i < m; i++){
matrix[i][0] = 0;
}
}
if(judgeRow == 1){
for(int i = 0; i < n; i++){
matrix[0][i] = 0;
}
}
}
}
总结: 无