中等 | 模拟 |

一. 题目描述

给你一个 **m****n** 列的矩阵 **matrix** ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

二. 题目示例

LeetCode54. 螺旋矩阵 - 图1 :::tips 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5] ::: LeetCode54. 螺旋矩阵 - 图2 :::tips 输入: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] :::

三. 题目解答

1. 思路

按照模拟的思路,分别进行上右下左的遍历,即一圈的遍历。圈结束后,会剩下一行或一列或一项,再判断进行遍历。
LeetCode54. 螺旋矩阵 - 图3

  1. 圈的遍历
    • 如果一条边从头遍历到底,则下一条边遍历的起点随之变化
    • 选择不遍历到底,可以减小横向、竖向遍历之间的影响
    • 一轮迭代结束时,4条边的两端同时收窄 1
    • 一轮迭代所做的事情变得很清晰:遍历一个“圈”,遍历的范围收缩为内圈
    • 一层层向里处理,按顺时针依次遍历:上、右、下、左。
    • 不再形成“环”了,就会剩下:一行或一列,然后单独判断
  2. 四个边界
    • 上边界 **top**: **0**
    • 下边界 **bottom**: **matrix.length - 1**
    • 左边界 **left**: **0**
    • 右边界 **right**: **matrix[0].length - 1**
  3. 循环条件
    • 矩阵不一定是方阵,**top < bottom && left < right** 是循环的条件
    • 无法构成“环”了,就退出循环,退出时可能是这 3 种情况之一:
      • **top == bottom && left < right** —— 剩一行
      • **top < bottom && left == right** —— 剩一列
      • **top == bottom && left == right** —— 剩一项(也算 一行/列)
  4. 处理剩下的单行或单列
    • 因为是按顺时针推入结果数组的,所以:
      • 剩下的一行,从左至右 依次推入结果数组
      • 剩下的一列,从上至下 依次推入结果数组

        2. 代码

        ```javascript /**
    • @param {number[][]} matrix
    • @return {number[]} / var spiralOrder = function(matrix) { let result = []; const m = matrix.length; const n = matrix[0].length; let top = 0, bottom = m-1; // [i][] let left = 0, right = n-1; // [*][j] while(top < bottom && left < right){ // 有头没尾循环 // 上 for(let j=left; j<right; j++){
      1. result.push(matrix[top][j]);
      } // 右 for(let i=top; i<bottom; i++){
         result.push(matrix[i][right]);
      
      } // 下 for(let j=right; j>left; j—){
         result.push(matrix[bottom][j]);
      
      } // 左 for(let i=bottom; i>top; i—){
         result.push(matrix[i][left]);
      
      } top++; right—; left++; bottom—; } // 剩余一行: 上 if(top == bottom){ for(let j=left; j<=right; j++){
         result.push(matrix[top][j]);
      
      } } else if(left == right){ // 剩余一列 || 剩余一个: 右 for(let i=top; i<=bottom; i++){
         result.push(matrix[i][right]);
      
      } } return result; }; ```