第一个直觉是递归,先打印外层的一圈,然后像剥洋葱一样,打印内部的一圈,直到最后递归打印到最核心。

试着实现了一下,有小坑:

import java.util.*;

public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
        ArrayList<Integer> ret = new ArrayList<>();
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return ret;
        }
        doPrint(matrix, 0, matrix[0].length - 1, matrix.length - 1, 0, ret);
        return ret;
    }
    // top: 顶层行号, bottom: 底层行号
    // left: 左侧列号,right:右侧列号
    private void doPrint(int[][] matrix, int top, int right, int bottom, int left, List<Integer> ret) {
        if (top > bottom || left > right) {
            return; // 递归终止条件
        }
        for (int i = left; i <= right; ++i) {
            ret.add(matrix[top][i]);
        }
        for (int i = top + 1; i <= bottom; ++i) {
            ret.add(matrix[i][right]);
        }

        if (bottom > top) { // 如果只有一行,那就不用再重复加一遍了
            for(int i = right - 1; i >= left; --i) {
                ret.add(matrix[bottom][i]);
            }
        }

        if (right > left) { // 如果只有一列,也不用重复加一遍了
            for (int i = bottom - 1; i > top; --i) {
                ret.add(matrix[i][left]);
            }
        }
        doPrint(matrix, ++top, --right, --bottom, ++left, ret);
    }
}

实现的时候的2个坑:

  1. 没加递归终止条件,这是自己的问题,后来没想明白,把终止条件设置为top > bottom && left > right,这时有些情形已经越界了。
  2. 递归辅助函数中,如果只有一行或者只有一列的情形,此时不需要再重复打印,需要单独处理。

题解里面每次都打印第一行,然后将矩阵逆时针旋转的解法也很巧妙。