Open
Description
给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
示例 1:
输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]
示例 2:
输入:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12]
]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/spiral-matrix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
记录一个 visited 数组,从 0, 0
开始,按照右 -> 下 -> 左 -> 上
的方向不断前进,
直到遇到边界或者已经访问过的元素 则切换成下一个方向,每访问一个元素就把结果放入 res
数组中,最终当 res
的长度和矩阵大小一致时,就返回结果。
这里方向用 dirs
表示 4 个方向对应的偏移坐标,通过 currentIndex
指针不断递增来维护当前的方向,由于可能会超出方向数组的长度,所以每次取值都对 4 取余即可。
/**
* @param {number[][]} matrix
* @return {number[]}
*/
let spiralOrder = function (matrix) {
let maxY = matrix.length;
if (!maxY) return [];
let maxX = matrix[0].length;
// 记录一个 visited 数组
// 按照 右 -> 下 -> 左 -> 上 的方向不断前进
// 直到遇到边界或者已经访问过的元素 则切换成下一个方向
let dirs = [
[0, 1], // 右
[1, 0], // 下
[0, -1], // 左
[-1, 0], // 上
];
let currentDirIndex = 0;
let visited = [];
for (let y = 0; y < maxY; y++) {
visited[y] = [];
}
let isValid = (y, x) => {
return y >= 0 && y < maxY && x >= 0 && x < maxX && !visited[y][x];
};
let targetLength = maxY * maxX;
let res = [];
let helper = (y, x) => {
let val = matrix[y][x];
res.push(val);
if (res.length === targetLength) {
return res;
}
visited[y][x] = true;
let [diffY, diffX] = dirs[currentDirIndex % 4];
let nextY = y + diffY;
let nextX = x + diffX;
if (!isValid(nextY, nextX)) {
[diffY, diffX] = dirs[++currentDirIndex % 4];
nextY = y + diffY;
nextX = x + diffX;
}
helper(nextY, nextX);
};
helper(0, 0);
return res;
};