方法1
- 可以模拟螺旋矩阵的路径。初始位置是矩阵的左上角,初始方向是向右,当路径超出界限或者进入之前访问过的位置时,顺时针旋转,进入下一个方向。
- 判断路径是否进入之前访问过的位置需要使用一个与输入矩阵大小相同的辅助矩阵 dp,其中的每个元素表示该位置是否被访问过。当一个元素被访问时,将 dp 中的对应位置的元素设为已访问。
- 如何判断路径是否结束?由于矩阵中的每个元素都被访问一次,因此路径的长度即为矩阵中的元素数量,当路径的长度达到矩阵中的元素数量时即为完整路径,将该路径返回。
var spiralOrder = function (arr) {
if (!arr.length || !arr[0].length) return [];
var m = arr.length
var n = arr[0].length;
var dp = new Array(m).fill(0).map(() => new Array(n).fill(false));
var total = m * n;
var brr = new Array(total).fill(0);
var index = 0, i = 0, j = 0;
var crr = [[0, 1], [1, 0], [0, -1], [-1, 0]];
for (var k = 0; k < total; k++) {
brr[k] = arr[i][j];
dp[i][j] = true;
var ni = i + crr[index][0]
var nj = j + crr[index][1];
if (!(0 <= ni && ni < m &&
0 <= nj && nj < n &&
!(dp[ni][nj]))
) {
index = (index + 1) % 4;
}
i += crr[index][0];
j += crr[index][1];
}
return brr;
};
方法2
var spiralOrder = function (arr) {
if (!arr.length || !arr[0].length) return [];
var m = arr.length
var n = arr[0].length;
var brr = [];
var left = 0, right = n - 1, top = 0, bottom = m - 1;
while (left <= right && top <= bottom) {
for (var i = left; i <= right; i++) {
brr.push(arr[top][i]);
}
for (var j = top + 1; j <= bottom; j++) {
brr.push(arr[j][right]);
}
if (left < right && top < bottom) {
for (var i = right - 1; i > left; i--) {
brr.push(arr[bottom][i]);
}
for (var j = bottom; j > top; j--) {
brr.push(arr[j][left]);
}
}
[left, right, top, bottom] = [left + 1, right - 1, top + 1, bottom - 1];
}
return brr;
};