题目描述
给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
示例:
输入: matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出: [1,2,3,6,9,8,7,4,5]
提示:
m == matrix.lengthn == matrix[i].length1 <= m, n <= 10-100 <= matrix[i][j] <= 100
解法
边界收缩法
/**
* @param {number[][]} matrix
* @return {number[]}
*/
var spiralOrder = function (matrix) {
if (matrix.length === 0) return []
const res = []
let top = 0, bottom = matrix.length - 1, left = 0, right = matrix[0].length - 1
while (top < bottom && left < right) {
for (let i = left; i < right; i++) res.push(matrix[top][i]) // 上层
for (let i = top; i < bottom; i++) res.push(matrix[i][right]) // 右层
for (let i = right; i > left; i--) res.push(matrix[bottom][i])// 下层
for (let i = bottom; i > top; i--) res.push(matrix[i][left]) // 左层
right--
top++
bottom--
left++ // 四个边界同时收缩,进入内层
}
if (top === bottom) // 剩下一行,从左到右依次添加
for (let i = left; i <= right; i++) res.push(matrix[top][i])
else if (left === right) // 剩下一列,从上到下依次添加
for (let i = top; i <= bottom; i++) res.push(matrix[i][left])
return res
};
很明显,如果每个方向遍历到前一个位置停下,这样当每次一个顺时针循环下来,上下左右的起始位置到刚好减一。这样方便我们遍历完一个方向后,找到下一个遍历方向的起点 我们定义每次遍历的方阵的四个边界为:
top初始化为0botttom初始化为matrix.length-1 即矩阵的行数left初始化为0right初始化为matrix[0]-1 即矩阵的列数
创建res数组存放结果
然后我们右下左上这四个方向遍历一遍为一次"环"遍历,当构不成环(即只剩下一列/一行)时,我们结束这个环遍历,最后将剩下的一行/一列按顺时针方向添加进结果中
具体实现:
通过while循环来实现一直环遍历 ,结束的条件就是只剩一行/列top < bottom && left < right。
在while循环内部:
- 从左到右遍历:for (let i = left; i < right; i++) res.push(matrix[top][i])
- 从上到下遍历:for (let i = top; i < bottom; i++) res.push(matrix[i][right])
- 从右到左遍历: for (let i = right; i > left; i--) res.push(matrix[bottom][i])
- 从下到上遍历: for (let i = bottom; i > top; i--) res.push(matrix[i][left])
- 一个环遍历后,将边界向内收缩 right-- 、 top++ 、 bottom-- 、 left++
当所有的环遍历结束后,添加上剩下的一行/列
- 剩下一行(top===bottom)
- for (let i = left; i <= right; i++) res.push(matrix[top][i])
- 从左到右(因为是顺时针方向,且最后剩余部分构不成一个环,那么这个是这个层首次被访问,应该是从左到右)
- 剩下一列(left===right)
- for (let i = top; i <= bottom; i++) res.push(matrix[i][left])
- 从上到下 (同样是该层首次被访问,从上到下)
最后返回res
时间、空间复杂度
时间复杂度:
算法遍历矩阵中的每个元素恰好一次。
空间复杂度: (不计输出数组)
仅使用了 top, bottom, left, right 等常数额外的空间。