Matrix Inplace Operations
当我们需要 in-place 处理矩阵的时候,最简便直接的思路往往是“多个 pass”的,即用一次 pass 做标记,第二次甚至第三次 pass 再做实际处理。
public class Solution {
public void setZeroes(int[][] matrix) {
if(matrix == null || matrix.length == 0) return;
int rows = matrix.length;
int cols = matrix[0].length;
boolean firstRowZero = false;
boolean firstColZero = false;
for(int i = 0; i < rows; i++) if(matrix[i][0] == 0) firstColZero = true;
for(int i = 0; i < cols; i++) if(matrix[0][i] == 0) firstRowZero = true;
for(int i = 1; i < rows; i++){
for(int j = 1; j < cols; j++){
if(matrix[i][j] == 0) matrix[i][0] = matrix[0][j] = 0;
}
}
for(int i = 1; i < rows; i++){
for(int j = 1; j < cols; j++){
if(matrix[i][0] == 0 || matrix[0][j] == 0) matrix[i][j] = 0;
}
}
if(firstRowZero) for(int i = 0; i < cols; i++) matrix[0][i] = 0;
if(firstColZero) for(int i = 0; i < rows; i++) matrix[i][0] = 0;
}
}从以上两题可以发现,当我们需要 in-place 处理矩阵的时候,最简便直接的思路往往是“多个 pass”的,即用一次 pass 做标记,第二次甚至第三次 pass 再做实际处理。
另一种更直观更好理解的方式是存两个指针,a , b , 分别代表着当前处理这层的 “左上” 和 “右下” 位置 (矩阵是正方形),然后 offset 和各种 index 就好计算很多,也完全不需要考虑到 base case 上时候的各种特殊情况。
维护四个边界,按顺序输出之后步步收缩。
特别注意处理 “下” 和 “左” 边界的时候,有可能当前这层只有一行,或者一列,已经输出过了不需要重复输出。所以这两条边的循环上要注意加一个判断条件。
(G) 对角打印矩阵,左上到右下,按对角线长度降序打印
Last updated