## 解题思路:\n\n根据题目示例 `matrix = [[1,2,3],[4,5,6],[7,8,9]]` 的对应输出 `[1,2,3,6,9,8,7,4,5]` 可以发现,顺时针打印矩阵的顺序是 **“从左向右、从上向下、从右向左、从下向上”** 循环。\n\n因此,考虑设定矩阵的 “左、上、右、下” 四个边界,模拟以上矩阵遍历顺序。\n
{:width=400}\n
### 算法流程:\n\n1. **空值处理:** 当 `matrix` 为空时,直接返回空列表 `[]` 即可。\n2. **初始化:** 矩阵 左、右、上、下 四个边界 `l` , `r` , `t` , `b` ,用于打印的结果列表 `res` 。\n3. **循环打印:** “从左向右、从上向下、从右向左、从下向上” 四个方向循环打印。\n 1. 根据边界打印,即将元素按顺序添加至列表 `res` 尾部。\n 2. 边界向内收缩 1 (代表已被打印)。\n 3. 判断边界是否相遇(是否打印完毕),若打印完毕则跳出。\n4. **返回值:** 返回 `res` 即可。\n
| 打印方向 | 1. 根据边界打印 | 2. 边界向内收缩 | 3. 是否打印完毕 |\n| -------- | ---------------------- | ----------------- | --------------- |\n| 从左向右 | 左边界`l` ,右边界 `r` | 上边界 `t` 加 $1$ | 是否 `t > b` |\n| 从上向下 | 上边界 `t` ,下边界`b` | 右边界 `r` 减 $1$ | 是否 `l > r` |\n| 从右向左 | 右边界 `r` ,左边界`l` | 下边界 `b` 减 $1$ | 是否 `t > b` |\n| 从下向上 | 下边界 `b` ,上边界`t` | 左边界 `l` 加 $1$ | 是否 `l > r` |\n
<,,,,,>\n
## 代码:\n\nJava, C++ 代码利用了 `++` 操作的便利性,详情可见 [++i 和 i++ 的区别](https://www.jianshu.com/p/b62eac216499) 。\n
- `res[x++]` 等价于先给 `res[x]` 赋值,再给 `x` 自增 $1$ 。\n- `++t > b` 等价于先给 `t` 自增 $1$ ,再判断 `t > b` 逻辑表达式。\n
> TIPS: 请注意区分数字 `1` 和字母 `l` 。\n
```Python []\nclass Solution:\n def spiralOrder(self, matrix: List[List[int]]) -> List[int]:\n if not matrix: return []\n l, r, t, b, res = 0, len(matrix[0]) - 1, 0, len(matrix) - 1, []\n while True:\n for i in range(l, r + 1): res.append(matrix[t][i]) # left to right
t += 1
if t > b: break
for i in range(t, b + 1): res.append(matrix[i][r]) # top to bottom
r -= 1
if l > r: break
for i in range(r, l - 1, -1): res.append(matrix[b][i]) # right to left
b -= 1
if t > b: break
for i in range(b, t - 1, -1): res.append(matrix[i][l]) # bottom to top
l += 1
if l > r: break
return res
```\n
```Java []\nclass Solution {\n public List<Integer> spiralOrder(int[][] matrix) {\n if (matrix.length == 0)\n return new ArrayList<Integer>();\n int l = 0, r = matrix[0].length - 1, t = 0, b = matrix.length - 1, x = 0;\n Integer[] res = new Integer[(r + 1) * (b + 1)];\n while (true) {\n for (int i = l; i <= r; i++) res[x++] = matrix[t][i]; // left to right
if (++t > b) break;\n for (int i = t; i <= b; i++) res[x++] = matrix[i][r]; // top to bottom
if (l > --r) break;\n for (int i = r; i >= l; i--) res[x++] = matrix[b][i]; // right to left
if (t > --b) break;\n for (int i = b; i >= t; i--) res[x++] = matrix[i][l]; // bottom to top
if (++l > r) break;\n }\n return Arrays.asList(res);\n }\n}\n```\n
```C++ []\nclass Solution {\npublic:\n vector<int> spiralOrder(vector<vector<int>>& matrix) {\n if (matrix.empty()) return {};\n int l = 0, r = matrix[0].size() - 1, t = 0, b = matrix.size() - 1;\n vector<int> res;\n while (true) {\n for (int i = l; i <= r; i++) res.push_back(matrix[t][i]); // left to right
if (++t > b) break;\n for (int i = t; i <= b; i++) res.push_back(matrix[i][r]); // top to bottom
if (l > --r) break;\n for (int i = r; i >= l; i--) res.push_back(matrix[b][i]); // right to left
if (t > --b) break;\n for (int i = b; i >= t; i--) res.push_back(matrix[i][l]); // bottom to top
if (++l > r) break;\n }\n return res;\n }\n};\n```\n
### 复杂度分析:\n
- **时间复杂度 $O(MN)$ :** $M, N$ 分别为矩阵行数和列数。\n- **空间复杂度 $O(1)$ :** 四个边界 `l` , `r` , `t` , `b` 使用常数大小的额外空间。\n
---\n
[](https://leetcode.cn/studyplan/selected-coding-interview/)\n\n本学习计划配有代码仓,内含测试样例与数据结构封装,便于本地调试。可前往我的[个人主页](https://leetcode.cn/u/jyd/)获取。\n