LeetCode热题(JS版)- 54. 螺旋矩阵

163 阅读2分钟

题目

给你一个 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]

提示:

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

思路

  • 本题的解法有多种,这里介绍一种比较简单的解法。 我们可以按照顺时针的方向依次遍历矩阵的每一个元素,并将其添加到结果数组中。具体来说,假设当前要遍历的区域左上角的坐标为 (top, left),右下角的坐标为 (bottom, right),则按照如下步骤遍历:
  • 从左到右遍历上侧元素,依次将其添加到结果数组中;
  • 从上到下遍历右侧元素,依次将其添加到结果数组中;
  • 如果 left < right 且 top < bottom,则从右到左遍历下侧元素,依次将其添加到结果数组中;
  • 如果 left < right 且 top < bottom,则从下到上遍历左侧元素,依次将其添加到结果数组中;
  • 将 left 和 top 分别加上 1,将 right 和 bottom 分别减去 1,然后回到步骤 1。 注意:在第 3 步和第 4 步中,需要判断 left < right 且 top < bottom,这是为了避免遍历到已经遍历过的元素。 最后,当 left == right 且 top == bottom 时,说明只剩下一个元素没有遍历,将其添加到结果数组中即可。
function spiralOrder(matrix: number[][]): number[] {
    const result = [];
    // 异常处理
    if(!matrix || !matrix.length || !matrix[0].length) return result
    
    // 记录,行索引范围:上-下,列索引范围:左-右
    let top = 0;
    let bottom = matrix.length - 1;
    let left = 0;
    let right = matrix[0].length - 1;

    // 顺时针遍历
    while(left <= right && top <= bottom) {
        // 上:从左到右
        for(let i = left; i <= right; i++) {
            result.push(matrix[top][i]);
        }
        top++;// 注意这里top要下移一行

        // 右:从上到下。
        for(let i = top; i <= bottom; i++) {
            result.push(matrix[i][right]);
        }
        right--;// 注意这里right要左移一列

        if(left <= right && top <= bottom) {// top,left有变动,所以需要重新判断下
            // 下:从右到左。
            for(let i = right; i >= left; i--) {
                result.push(matrix[bottom][i]);
            }
            bottom--;// 注意这里bottom要上移一行

            // 左:从下到上。
            for(let i = bottom; i >= top; i--) {
                result.push(matrix[i][left]);
            } 
            left++;// 注意这里left要右移一行
            
        }
    }

    return result;
};

image.png

总结

  • 时间复杂度:O(mn)O(mn),其中 mmnn 分别是矩阵的行数和列数。
  • 空间复杂度:O(1)O(1)

除了上述的解法,还有以下两种常见的解法:

  • 解法一:模拟旋转矩阵 这种解法的思路是将矩阵逆时针旋转90度,然后按照从左到右、从上到下的顺序遍历矩阵,并将遍历到的元素添加到结果数组中。具体来说,我们可以先将矩阵逆时针旋转90度,然后按照行的顺序遍历矩阵,并将遍历到的元素添加到结果数组中。时间复杂度为 O(mn)O(mn),空间复杂度为 O(mn)O(mn)

  • 解法二:按层遍历 这种解法的思路是按照从外到内的顺序遍历矩阵,并将遍历到的元素添加到结果数组中。具体来说,我们可以定义一个变量 layerlayer 表示当前要遍历的层数,从外层开始依次往里面遍历。对于每一层,我们可以将其分为四个边,从左到右、从上到下依次遍历,将遍历到的元素添加到结果数组中。时间复杂度为 O(mn)O(mn),空间复杂度为 O(1)O(1)

  • 综上所述,这道题目有多种解法,每种解法都有其优点和局限性,具体选择哪种解法需要根据实际情况进行选择。