螺旋矩阵
1. 题目呈现
难度等级:🟡 中等
核心考察点:矩阵、模拟
给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
示例 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]
2. 解题思路拆解
方法:模拟层层遍历
这道题没有太复杂的算法思想,核心在于模拟螺旋移动的过程,并精确控制边界。
定义边界:
- 我们需要四个变量来表示当前的边界:
top,bottom,left,right。 - 初始时:
top = 0,bottom = m-1,left = 0,right = n-1。
- 我们需要四个变量来表示当前的边界:
模拟过程:
- 只要
left <= right且top <= bottom,就继续循环。 - 向右移动:从
left到right遍历top行。遍历完,top++。 - 向下移动:从
top到bottom遍历right列。遍历完,right--。 - 向左移动:需要先检查
top <= bottom(防止重复遍历)。从right到left遍历bottom行。遍历完,bottom--。 - 向上移动:需要先检查
left <= right(防止重复遍历)。从bottom到top遍历left列。遍历完,left++。
- 只要
终止条件:
- 当边界交错时(
left > right或top > bottom),循环结束。
- 当边界交错时(
3. 代码实现
javascript
/**
* @param {number[][]} matrix
* @return {number[]}
*/
var spiralOrder = function(matrix) {
if (!matrix.length || !matrix[0].length) {
return [];
}
const result = [];
let top = 0;
let bottom = matrix.length - 1;
let left = 0;
let right = matrix[0].length - 1;
while (top <= bottom && left <= right) {
// 1. 向右移动
for (let i = left; i <= right; i++) {
result.push(matrix[top][i]);
}
top++; // 上边界下移
// 2. 向下移动
for (let i = top; i <= bottom; i++) {
result.push(matrix[i][right]);
}
right--; // 右边界左移
// 3. 向左移动
// 注意:需要检查 top <= bottom,因为 top 刚刚变了
if (top <= bottom) {
for (let i = right; i >= left; i--) {
result.push(matrix[bottom][i]);
}
bottom--; // 下边界上移
}
// 4. 向上移动
// 注意:需要检查 left <= right,因为 right 刚刚变了
if (left <= right) {
for (let i = bottom; i >= top; i--) {
result.push(matrix[i][left]);
}
left++; // 左边界右移
}
}
return result;
};代码执行演示
输入 matrix = [[1,2,3],[4,5,6],[7,8,9]]
- 初始:
top=0, bottom=2, left=0, right=2 - 第 1 轮循环:
- 向右:遍历
row 0,col 0->2。res=[1,2,3]。top变为 1。 - 向下:遍历
col 2,row 1->2。res=[1,2,3,6,9]。right变为 1。 - 检查:
top(1) <= bottom(2),通过。 - 向左:遍历
row 2,col 1->0。res=[1,2,3,6,9,8,7]。bottom变为 1。 - 检查:
left(0) <= right(1),通过。 - 向上:遍历
col 0,row 1->1。res=[1,2,3,6,9,8,7,4]。left变为 1。
- 向右:遍历
- 第 2 轮循环:
- 当前:
top=1, bottom=1, left=1, right=1。满足条件。 - 向右:遍历
row 1,col 1->1。res=[..., 5]。top变为 2。 - 向下:遍历
col 1,row 2->1(不执行)。right变为 0。 - 检查:
top(2) <= bottom(1),不通过。跳过向左。 - 检查:
left(1) <= right(0),不通过。跳过向上。
- 当前:
- 循环结束。返回
[1,2,3,6,9,8,7,4,5]。
4. 复杂度分析
| 维度 | 描述 |
|---|---|
| 时间复杂度 | $O(mn)$。我们需要遍历矩阵中的每个元素一次。 |
| 空间复杂度 | $O(1)$。除了输出数组外,只需要常数空间存储边界变量。 |
