LeetCode 54 Spiral Matrix (Tag:Array Difficulty:Medium)

252 阅读2分钟

这是我参与8月更文挑战的第12天,活动详情查看:8月更文挑战

前言

关于 LeetCode 数组类型题目的相关解法,可见LeetCode 数组类型题目做前必看,分类别解法总结了题目,可以用来单项提高。觉得有帮助的话,记得多多点赞关注哦,感谢!

题目描述

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

示例 1:
image.png
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]

示例 2:
image.png
输入: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…

题解

这道题目其实就是如何顺时针遍历矩阵. 通常这种螺旋遍历的问题, 主要有下面几个要点.

  1. 定义方向数组. 对于这道题来讲, 分别有四个方向, 从左到右 [0, 1], 从上到下 [1, 0], 从右到左 [0, -1], 从下到上 [-1, 0], 这些方向数组表示每次移动时, x 和 y 要变化值.

  2. 定义边界. 分别初始化上边界和左边界为 0, 初始化右边界和下边界为 n - 1.

  3. 更新方向和边界大小. 当向前走时, 每次走到边界位置, 就改变方向, 并且所小对应的边界. 比如当走到第一行最后一个元素时, 更改走的方向为 [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
};