给定一个包含 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]
设置四个边界,四个方向,一个方向只能更改一个坐标值。
/**
* @param {number[][]} matrix
* @return {number[]}
*/
var spiralOrder = function(matrix) {
let result = [];
if(matrix.length === 0) {
return result;
}
let m = matrix.length;
let n = matrix[0].length;
let maxCount = m * n;
// 定义四个边界
let boundTop = 0; // 上边界
let boundBottom = m - 1; // 下边界
let boundLeft = 0; // 左变界
let boundRight = n - 1; // 右边界
// 定义四个方向,根据不同状态进行切换
// 如果右边界为0(只有1个值),则初始化方向为下
let direction = boundRight === 0 ? "down" : 'right';
let i = 0; // 列坐标
let j = 0; // 行坐标
for(let k = 0; k < maxCount; k++) {
result.push(matrix[i][j]);
/**
* 1. 在其方向为右 且未触碰边界值时 列向右走(j++)
* 2. 当触碰时转向,应该向下走,且上边界加1
*/
if(direction === 'right') {
j++;
if(j === boundRight) {
direction = 'down';
boundTop++;
}
}
/**
* 1. 在其方向为下 且未触碰边界值时 向下走(i++)
* 2. 当触碰时转向,应该向左走,且右边界减1
*/
else if(direction === 'down') {
i++;
if(i === boundBottom) {
direction = 'left';
boundRight--;
}
}
/**
* 1. 在其方向为左 且未触碰边界值时 向左走(j--)
* 2. 当触碰时转向,应该向上走,且下边界减1
*/
else if(direction === 'left') {
j--;
if(j === boundLeft) {
direction = 'up';
boundBottom--;
}
}
/**
* 1. 在其方向为上 且未触碰边界值时 向上走(i--)
* 2. 当触碰时转向,应该向右走,且左边界加1
*/
else if(direction === 'up') {
i--;
if(i === boundTop) {
direction = 'right';
boundLeft++;
}
}
}
return result;
};
给定一个正整数 n,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:
输入: 3
输出:
[
[ 1, 2, 3 ],
[ 8, 9, 4 ],
[ 7, 6, 5 ]
]
和 螺旋矩阵的解法类似,只不过现在是要将数组打印出来。
/**
* @param {number[][]} matrix
* @return {number[]}
*/
var generateMatrix = function(n) {
if(n === 0) {
return [];
}
// 初始化
let result = new Array(n);
for(let i = 0; i < n; i++) {
result[i] = [];
}
let maxCount = n * n;
// 定义四个边界
let boundTop = 0; // 上边界
let boundBottom = n - 1; // 下边界
let boundLeft = 0; // 左变界
let boundRight = n - 1; // 右边界
// 定义四个方向,根据不同状态进行切换
// 如果右边界为0(只有1个值),则初始化方向为下
let direction = boundRight === 0 ? "down" : 'right';
let i = 0; // 列坐标
let j = 0; // 行坐标
for(let k = 1; k <= maxCount; k++) {
// 进行赋值
result[i][j] = k;
/**
* 1. 在其方向为右 且未触碰边界值时 列向右走(j++)
* 2. 当触碰时转向,应该向下走,且上边界加1
*/
if(direction === 'right') {
j++;
if(j === boundRight) {
direction = 'down';
boundTop++;
}
}
/**
* 1. 在其方向为下 且未触碰边界值时 向下走(i++)
* 2. 当触碰时转向,应该向左走,且右边界减1
*/
else if(direction === 'down') {
i++;
if(i === boundBottom) {
direction = 'left';
boundRight--;
}
}
/**
* 1. 在其方向为左 且未触碰边界值时 向左走(j--)
* 2. 当触碰时转向,应该向上走,且下边界减1
*/
else if(direction === 'left') {
j--;
if(j === boundLeft) {
direction = 'up';
boundBottom--;
}
}
/**
* 1. 在其方向为上 且未触碰边界值时 向上走(i--)
* 2. 当触碰时转向,应该向右走,且左边界加1
*/
else if(direction === 'up') {
i--;
if(i === boundTop) {
direction = 'right';
boundLeft++;
}
}
}
return result;
};