本题解法较为常规,难点在于要求的O(1)空间复杂度。
先看一下O(m+n)空间复杂度的解法,定义两个长度分别为矩阵长和宽的数组来记录矩阵各行或和各列是否出现了数字0。
然后在遍历一次将对应和行和列的全部元素赋值为0。
class Solution {
public void setZeroes(int[][] matrix) {
int m = matrix.length;
int n = matrix[0].length;
boolean[] rows = new boolean[m];
boolean[] cols = new boolean[n];
for(int i=0; i<m;i++){
for(int j=0; j<n;j++){
if(matrix[i][j]==0){
rows[i] = true;
cols[j] = true;
}
}
}
for(int i=0; i<m;i++){
for(int j=0; j<n;j++){
if(rows[i]){
matrix[i][j] = 0;
}
if(cols[j]){
matrix[i][j] = 0;
}
}
}
}
}
要让空间复杂度降低为O(a),可以定义两个变量记录矩阵第一行和第一列是否出现数字0,然后用矩阵的第一行和第一列来代替上述解法的两个数组来记录剩下的各行和各列是否出现数字0。
因此本题空间优化的思想是利用题目提供的数据结构本身来作为算法实现的一部分,这样就可以避免新开辟更多的使用空间。
class Solution {
public void setZeroes(int[][] matrix) {
int row = matrix.length;
int col = matrix[0].length;
boolean row0_flag = false;
boolean col0_flag = false;
// 第一行是否有零
for (int j = 0; j < col; j++) {
if (matrix[0][j] == 0) {
row0_flag = true;
break;
}
}
// 第一列是否有零
for (int i = 0; i < row; i++) {
if (matrix[i][0] == 0) {
col0_flag = true;
break;
}
}
// 把第一行第一列作为标志位
for (int i = 1; i < row; i++) {
for (int j = 1; j < col; j++) {
if (matrix[i][j] == 0) {
matrix[i][0] = matrix[0][j] = 0;
}
}
}
// 置0
for (int i = 1; i < row; i++) {
for (int j = 1; j < col; j++) {
if (matrix[i][0] == 0 || matrix[0][j] == 0) {
matrix[i][j] = 0;
}
}
}
if (row0_flag) {
for (int j = 0; j < col; j++) {
matrix[0][j] = 0;
}
}
if (col0_flag) {
for (int i = 0; i < row; i++) {
matrix[i][0] = 0;
}
}
}
}