class Solution {
public void setZeroes(int[][] mat) {
int m = mat.length, n = mat[0].length;
// 1. 扫描「首行」和「首列」记录「首行」和「首列」是否该被置零
boolean r0 = false, c0 = false;
for (int i = 0; i < m; i++) {
if (mat[i][0] == 0) {
r0 = true;
break;
}
}
for (int j = 0; j < n; j++) {
if (mat[0][j] == 0) {
c0 = true;
break;
}
}
// 2.1 扫描「非首行首列」的位置,如果发现零,将需要置零的信息存储到该行的「最左方」和「最上方」的格子内
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (mat[i][j] == 0) mat[i][0] = mat[0][j] = 0;
}
}
// 2.2 根据刚刚记录在「最左方」和「最上方」格子内的置零信息,进行「非首行首列」置零
for (int j = 1; j < n; j++) {
if (mat[0][j] == 0) {
for (int i = 1; i < m; i++) mat[i][j] = 0;
}
}
for (int i = 1; i < m; i++) {
if (mat[i][0] == 0) Arrays.fill(mat[i], 0);
}
// 3. 根据最开始记录的「首行」和「首列」信息,进行「首行首列」置零
if (r0) for (int i = 0; i < m; i++) mat[i][0] = 0;
if (c0) Arrays.fill(mat[0], 0);
}
}
自己实现:
public void setZeroes(int[][] matrix) {
/*思路:
* 1.如果先操作前面的元素则会对后面元素覆盖从而造成影响,则可以考虑存储。
* 2.采取原地O(1)操作,则可以考虑存储到行首和列首
* 3.特殊情况,只有一行或一列
* 4.注意[0][0]这个相交位置
* */
boolean rowHead = false;
boolean columnHead = false;
int r = matrix.length;
int c = matrix[0].length;
for (int i = 0; i < r; i++) {
if (matrix[i][0] == 0) {
rowHead = true;
}
}
for (int i = 0; i < c; i++) {
if (matrix[0][i] == 0) {
columnHead = true;
}
}
//要考虑特殊情况
if(r>=2&&c>=2){
for (int i = 0; i < r; i++) {
for (int j = 1; j < c; j++) {
if(matrix[i][j]==0){
matrix[i][0]=0;
matrix[0][j]=0;
}
}
}
}
//注意开始扫描行首和列首时,i,j应该从1开始,不然会影响后续判断(跳过[0][0])
for (int j = 1; j < c; j++) {
if(matrix[0][j]==0){
for (int i = 0; i < r; i++) {
matrix[i][j]=0;
}
}
}
for (int i = 1; i < r; i++) {
if(matrix[i][0]==0){
for (int j = 0; j < c; j++) {
matrix[i][j]=0;
}
}
}
if(rowHead){
for (int i = 0; i < r; i++) {
matrix[i][0]=0;
}
}
if(columnHead){
for (int i = 0; i < c; i++) {
matrix[0][i]=0;
}
}
}