题目描述

描述转载自力扣 https://leetcode-cn.com/problems/shun-shi-zhen-da-yin-ju-zhen-lcof/ ,返回值类型与牛客题有所不同,但本质是一样的。(力扣上标注的难度是简单,牛客上标注的难度是较难,这……)
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。

示例1

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]

示例2

输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]

解题思路

  1. 声明四个变量,分别为左界限 L,右界限 R,上界限 T,下界限 B。
    图片说明
  2. 先从左往右遍历,然后从上到下,从右往左,最后从下往上。循环这个操作,每次从左往右遍历完,T += 1,说明最上面这一行已经遍历过了,上界限 T 应该往下移了;从上往下遍历完, R -= 1,说明最右边这一列已经遍历过了,右界限 R 应该往左移了;其他遍历操作也是如此。当四个界限中,T 和 B,或者 L 和 R 碰撞在一起,说明遍历完成,退出循环。
  3. 值得注意的是,需要考虑非方阵的情况,比如矩阵 A[3][4],因为行数比列数少,T 和 B 碰撞时 L 和 R 仍未碰撞,若此时还在循环体内,会继续执行遍历操作。所以在循环体内,需要时刻监控界限碰撞的情况。
    图片说明

Java代码实现

class Solution {
    public int[] spiralOrder(int[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return new int[0];
        int t = 0, b = matrix.length - 1, 
            l = 0, r = matrix[0].length - 1,
            len = matrix.length * matrix[0].length, cur = 0;

        int[] res = new int[len];
        while (l <= r && t <= b) {
            // go right
            for (int i = l; i <= r; ++i) {
                res[cur++] = matrix[t][i];
            }
            ++t;
            if (l > r || t > b) break;
            // go down
            for (int i = t; i <= b; ++i) {
                res[cur++] = matrix[i][r];
            }
            --r;
            if (l > r || t > b) break;
            // go left
            for (int i = r; i >= l; --i) {
                res[cur++] = matrix[b][i];
            }
            --b;
            if (l > r || t > b) break;
            // go up
            for (int i = b; i >= t; --i) {
                res[cur++] = matrix[i][l];
            }
            ++l;
        }
        return res;
    }
}