快一个月没刷题了,最近工作有些忙,今天闲下来两小时,刷一道
题目描述
给你一个 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]
解题思路
控制上下边界、左右边界。每一次循环走一圈,走完一圈上下左右边界往内部压缩。结束条件是left>right top>bottom
- 首先初始化上边界为第0行,下边界为最后一行,左边界是第0列,右边界是最后一列。可以看出边界就是要加到res(返回数组)的一圈。
- 接下来一个循环,条件是true(无限循环),虽然终止条件是
left>right top>bottom
,但是在走一圈的过程中就可能会触发终止条件,而不是一圈结束了才会触发终止条件。因此在遍历四个时,每遍历一个边就判断一次终止条件
代码
var spiralOrder = function(matrix) {let left = 0; // 初始化左边界为第0列let right = matrix[0].length-1; // 初始化右边界为最后一列let top = 0; // 初始化上边界为第0行let bottom = matrix.length-1; // 初始化下边界为最后一行let res = []; // 初始化结果数组,用于存储最终的螺旋顺序元素while(true){ // 开始一个无限循环for(let i=left;i<=right;i++){ // 从左到右遍历第一行res.push(matrix[top][i]); // 将第一行的元素添加到结果数组}top++; // 遍历完第一行后,上边界下移if(top>bottom)break; // 如果上边界超过了下边界,结束循环for(let i=top;i<=bottom;i++){ // 从上到下遍历最后一列res.push(matrix[i][right]); // 将最后一列的元素添加到结果数组}right--; // 遍历完最后一列后,右边界左移if(right<left)break; // 如果右边界小于左边界,结束循环for(let i=right;i>=left;i--){ // 从右到左遍历最后一行res.push(matrix[bottom][i]); // 将最后一行的元素添加到结果数组}bottom--; // 遍历完最后一行后,下边界上移if(bottom<top) break; // 如果下边界小于上边界,结束循环for(let i=bottom;i>=top;i--){ // 从下到上遍历第一列res.push(matrix[i][left]); // 将第一列的元素添加到结果数组}left++; // 遍历完第一列后,左边界右移if(left>right) break; // 如果左边界超过了右边界,结束循环}return res; // 返回结果数组
};
案例分析
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
逐步分析:
-
初始化边界:
left = 0
right = 2
top = 0
bottom = 2
-
第一次循环:
- 从左到右遍历第一行(
top
行):[1, 2, 3]
添加到res
res = [1, 2, 3]
top++
(top = 1
)- 检查边界:
top <= bottom
(1 <= 2
),继续。
- 从左到右遍历第一行(
-
第二次循环:
- 从上到下遍历最后一列(
right
列):[6, 9]
添加到res
res = [1, 2, 3, 6, 9]
right--
(right = 1
)- 检查边界:
right >= left
(1 >= 0
),继续。
- 从上到下遍历最后一列(
-
第三次循环:
- 从右到左遍历最后一行(
bottom
行):[8, 7]
添加到res
res = [1, 2, 3, 6, 9, 8, 7]
bottom--
(bottom = 1
)- 检查边界:
bottom >= top
(1 >= 1
),继续。
- 从右到左遍历最后一行(
-
第四次循环:
- 从下到上遍历第一列(
left
列):[4]
添加到res
res = [1, 2, 3, 6, 9, 8, 7, 4]
left++
(left = 1
)- 检查边界:
left <= right
(1 <= 1
),继续。
- 从下到上遍历第一列(
-
第五次循环:
- 从左到右遍历第二行(
top
行):[5]
添加到res
res = [1, 2, 3, 6, 9, 8, 7, 4, 5]
top++
(top = 2
)- 检查边界:
top > bottom
(2 > 1
),循环结束。
- 从左到右遍历第二行(
结论:
循环在第五次遍历后结束,因为此时 top > bottom
的条件满足。因此,最终结果数组 res
为 [1, 2, 3, 6, 9, 8, 7, 4, 5]
。