Skip to content

螺旋矩阵-54 #112

Open
Open
@sl1673495

Description

@sl1673495

给定一个包含  m x n  个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。

示例 1:

输入:
[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]
示例 2:

输入:
[
  [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)
链接:https://leetcode-cn.com/problems/spiral-matrix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

记录一个 visited 数组,从 0, 0 开始,按照右 -> 下 -> 左 -> 上的方向不断前进,

直到遇到边界或者已经访问过的元素 则切换成下一个方向,每访问一个元素就把结果放入 res 数组中,最终当 res 的长度和矩阵大小一致时,就返回结果。

这里方向用 dirs 表示 4 个方向对应的偏移坐标,通过 currentIndex 指针不断递增来维护当前的方向,由于可能会超出方向数组的长度,所以每次取值都对 4 取余即可。

/**
 * @param {number[][]} matrix
 * @return {number[]}
 */
let spiralOrder = function (matrix) {
  let maxY = matrix.length;
  if (!maxY) return [];
  let maxX = matrix[0].length;

  // 记录一个 visited 数组
  // 按照 右 -> 下 -> 左 -> 上 的方向不断前进
  // 直到遇到边界或者已经访问过的元素 则切换成下一个方向
  let dirs = [
    [0, 1], // 右
    [1, 0], // 下
    [0, -1], // 左
    [-1, 0], // 上
  ];

  let currentDirIndex = 0;

  let visited = [];
  for (let y = 0; y < maxY; y++) {
    visited[y] = [];
  }
  let isValid = (y, x) => {
    return y >= 0 && y < maxY && x >= 0 && x < maxX && !visited[y][x];
  };

  let targetLength = maxY * maxX;
  let res = [];

  let helper = (y, x) => {
    let val = matrix[y][x];
    res.push(val);

    if (res.length === targetLength) {
      return res;
    }

    visited[y][x] = true;
    let [diffY, diffX] = dirs[currentDirIndex % 4];
    let nextY = y + diffY;
    let nextX = x + diffX;
    if (!isValid(nextY, nextX)) {
      [diffY, diffX] = dirs[++currentDirIndex % 4];
      nextY = y + diffY;
      nextX = x + diffX;
    }
    helper(nextY, nextX);
  };

  helper(0, 0);

  return res;
};

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions