LeetCode —— 54. 螺旋矩阵

233 阅读2分钟

启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第14天,点击查看活动详情

该题是螺旋数组题型第二题。

题目来源

54. 螺旋矩阵 - 力扣(LeetCode)

题目描述(中等

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

示例1

spiral1.jpg

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

示例2

spiral.jpg

输入: 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]

提示

  • m==matrix.lengthm == matrix.length
  • n==matrix[i].lengthn == matrix[i].length
  • 1<=m,n<=101 <= m, n <= 10
  • 100<=matrix[i][j]<=100-100 <= matrix[i][j] <= 100

题目解析

该题与上一题 LeetCode —— 59. 螺旋矩阵 II - 掘金 十分相似。区别在于一个是遍历矩阵得到一个新数组,一个是生成一个螺旋矩阵。

模拟

该方法模拟螺旋矩阵的路径,初始位置是矩阵的左上角,初始方向为右,当路径超出界限或者进入到之前访问的位置时,顺时针旋转,进入到下一个方向。

判断是否进入到之前访问的位置,有两种方法,一种采用访问过的位置将数值重新赋值为 0 ,另一种便是重新定义一个相同大小的数组,在访问过的位置中,将值赋值给该数组。

代码

/**
 * @param {number[][]} matrix
 * @return {number[]}
 */
var spiralOrder = function(matrix) {
    let column = 0, row = 0,directions = [[0, 1], [1, 0], [0, -1], [-1, 0]], directionIndex = 0, result = [], lengthRow = matrix.length, lengthColumn = matrix[0]?.length, curNum = 0
    for (let i = 0;i < lengthColumn * lengthRow;i++) {
        curNum = matrix[row][column]
        matrix[row][column] = 0
        result.push(curNum)
        let nextRow = row + directions[directionIndex][0], nextColumn = column + directions[directionIndex][1]
        if (nextRow >= lengthRow || nextColumn >= lengthColumn || matrix[nextRow][nextColumn] == 0 || matrix[nextRow][nextColumn] == undefined) {
            directionIndex = (directionIndex + 1) % 4
        }
        row = row + directions[directionIndex][0]
        column = column + directions[directionIndex][1]
    }
    return result
};
  • 时间复杂度:O(mn)O(mn)。其中 mn 分别是矩阵的行数和列数。
  • 空间复杂度:O(1)O(1)

如图:

image.png

代码

var spiralOrder = function(matrix) {
    if (!matrix.length || !matrix[0].length) {
        return [];
    }
    const rows = matrix.length, columns = matrix[0].length;
    const visited = new Array(rows).fill(0).map(() => new Array(columns).fill(false));
    const total = rows * columns;
    const order = new Array(total).fill(0);

    let directionIndex = 0, row = 0, column = 0;
    const directions = [[0, 1], [1, 0], [0, -1], [-1, 0]];
    for (let i = 0; i < total; i++) { 
        order[i] = matrix[row][column];
        visited[row][column] = true;
        const nextRow = row + directions[directionIndex][0], nextColumn = column + directions[directionIndex][1];
        if (!(0 <= nextRow && nextRow < rows && 0 <= nextColumn && nextColumn < columns && !(visited[nextRow][nextColumn]))) {
            directionIndex = (directionIndex + 1) % 4;
        }
        row += directions[directionIndex][0];
        column += directions[directionIndex][1];
    }
    return order;
};
  • 时间复杂度:O(mn)O(mn) 。其中 mn 分别是矩阵的行数和列数。
  • 空间复杂度:O(mn)O(mn) 。需要创建一个 m×nm \times n 大小的矩阵数组存储遍历的位置。

如图:

image.png

执行用时和内存消耗仅供参考,大家可以多提交几次。如有更好的想法,欢迎大家提出。