这是我参与8月更文挑战的第12天,活动详情查看:8月更文挑战
前言
关于 LeetCode 数组类型题目的相关解法,可见LeetCode 数组类型题目做前必看,分类别解法总结了题目,可以用来单项提高。觉得有帮助的话,记得多多点赞关注哦,感谢!
题目描述
给你一个 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]
链接:leetcode-cn.com/problems/sp…
题解
这道题目其实就是如何顺时针遍历矩阵. 通常这种螺旋遍历的问题, 主要有下面几个要点.
-
定义方向数组. 对于这道题来讲, 分别有四个方向, 从左到右 [0, 1], 从上到下 [1, 0], 从右到左 [0, -1], 从下到上 [-1, 0], 这些方向数组表示每次移动时, x 和 y 要变化值.
-
定义边界. 分别初始化上边界和左边界为 0, 初始化右边界和下边界为 n - 1.
-
更新方向和边界大小. 当向前走时, 每次走到边界位置, 就改变方向, 并且所小对应的边界. 比如当走到第一行最后一个元素时, 更改走的方向为 [1, 0], 同时上边界由 1 变为 0. 当前遍历的方向我们可以用一个变量 i 来表示, i 的范围在 0-3, 即方向数组的大小.
综合上面3步, 我们可以理解下面的代码.
时间复杂度 O(mn), 空间复杂度 O(1)
/**
* @param {number[][]} matrix
* @return {number[]}
*/
var spiralOrder = function(matrix) {
let res = []
let m = matrix.length
let n = matrix[0].length
// 定义四个边界
let left = up = 0
let right = n - 1
let bottom = m - 1
// 遍历起点
let x = 0
let y = 0
// 方向数组
const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]]
// 决定方向的变量
let i = 0
while (res.length < m * n) {
res.push(matrix[x][y])
// 到达右边界
if (i === 0 && y === right) {
++up
++i
// 达到下边界
} else if (i === 1 && x === bottom) {
--right
++i
// 到达左边界
} else if (i === 2 && y === left) {
--bottom
++i
// 到达上边界
} else if (i === 3 && x === up) {
++left
++i
}
// 更新方向
i %= 4
// 向前遍历
x += dir[i][0]
y += dir[i][1]
}
return res
};