小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
题目
给你一个 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]
提示:
m == matrix.lengthn == matrix[i].length1 <= m, n <= 10-100 <= matrix[i][j] <= 100
解题思路
思路1
- 首先要判断空数组,返回
[] - 无限循环,访问四条边,若越界,则说明访问完了,退出
const spiralOrder = matrix => {
const res = [];
// 定义行、列
// 可能是空数组,所以加一个'?'
const [m, n] = [matrix.length, matrix[0]?.length];
if (!m || !n) return res;
// 初始化:左、右、上、下
let [left, right, up, down] = [0, n - 1, 0, m - 1];
while (1) {
// 访问上边,从左到右,访问完毕后,up++
for (let j = left; j <= right; j++) res.push(matrix[up][j]);
up++;
// 若up比down大,说明都访问完了,退出
if (up > down) break;
// 以下同理
for (let i = up; i <= down; i++) res.push(matrix[i][right]);
right--;
if (right < left) break;
for (let j = right; j >= left; j--) res.push(matrix[down][j]);
down--;
if (down < up) break;
for (let i = down; i >= up; i--) res.push(matrix[i][left]);
left++;
if (left > right) break;
}
return res;
};
常规法
var spiralOrder = function (arr) {
// 方向默认右边
let dir = 'right';
// m 行 n 列
let m = arr.length, n = arr[0].length;
let y = 0, x = 0, r = [];
// 缓存结果
let map = {};
while (true) {
let key = `${y},${x}`;
r.push(arr[y][x]);
map[key] = 1;
const canRight = x < n - 1 && !map[`${y},${x + 1}`];
const canDown = (y < m - 1) && !map[`${y + 1},${x}`];
const canLeft = x > 0 && !map[`${y},${x - 1}`];
const canTop = y > 0 && !map[`${y - 1},${x}`];
if (dir === 'right') {
if (canRight) {
x++
continue
}
if (canDown) {
dir = 'bottom';
y++;
continue
}
// 无路可走,退出
break;
}
if (dir === 'bottom') {
if (canDown) {
y++;
continue
}
if (canLeft) {
dir = 'left';
x--;
continue;
}
// 无路可走,退出
break;
}
if (dir === 'left') {
if (canLeft) {
x--;
continue;
}
if (canTop) {
y--;
dir = 'top';
continue;
}
// 无路可走,退出
break;
}
if (dir === 'top') {
if (canTop) {
y--;
continue;
}
if (canRight) {
x++;
dir = 'right';
continue;
}
// 无路可走,退出
break;
}
};
return r;
}