【数据结构与算法】力扣 54. 螺旋矩阵

问题描述

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

示例 1:

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

示例 2:

复制代码
输入: 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 表示当前上边界,初始为 0。
    • bottom 表示当前下边界,初始为 m - 1
    • left 表示当前左边界,初始为 0。
    • right 表示当前右边界,初始为 n - 1
  • 循环遍历矩阵

    • 从左到右遍历顶部边界,然后将 top 下移。
    • 从上到下遍历右边界,然后将 right 左移。
    • 从右到左遍历底部边界(如果还没有遍历过),然后将 bottom 上移。
    • 从下到上遍历左边界(如果还没有遍历过),然后将 left 右移。
js 复制代码
function spiralOrder(matrix) {
    if (matrix.length === 0) return [];

    const result = [];
    let top = 0, bottom = matrix.length - 1;
    let left = 0, right = matrix[0].length - 1;

    while (top <= bottom && left <= right) {
        // 从左到右遍历顶部
        for (let i = left; i <= right; i++) {
            result.push(matrix[top][i]);
        }
        top++;

        // 从上到下遍历右边界
        for (let i = top; i <= bottom; i++) {
            result.push(matrix[i][right]);
        }
        right--;

        // 从右到左遍历底部
        if (top <= bottom) {
            for (let i = right; i >= left; i--) {
                result.push(matrix[bottom][i]);
            }
            bottom--;
        }

        // 从下到上遍历左边界
        if (left <= right) {
            for (let i = bottom; i >= top; i--) {
                result.push(matrix[i][left]);
            }
            left++;
        }
    }

    return result;
}

// 测试示例
console.log(spiralOrder([[1,2,3],[4,5,6],[7,8,9]])); // 输出: [1,2,3,6,9,8,7,4,5]
console.log(spiralOrder([[1,2,3,4],[5,6,7,8],[9,10,11,12]])); // 输出: [1,2,3,4,8,12,11,10,9,5,6,7]

遍历矩阵

  • 按顺时针顺序依次遍历上、右、下、左四个边界,将对应的元素添加到结果数组中。
  • 每遍历完一个边界,就缩小对应的边界值,逐渐向内层推进。
  • 使用条件判断来避免重复遍历同一行或同一列。

if (top <= bottom)if (left <= right) 的作用:

  1. if (top <= bottom) 的作用

    • 当从左到右遍历完 top 行,以及从上到下遍历完 right 列后,会将 bottom 行从右到左遍历。
    • 然而,有可能在遍历 top 行之后,top 已经超过了 bottom(说明已经没有未遍历的行),所以需要先判断 top <= bottom 是否成立。如果不成立,说明不需要再遍历 bottom 行,避免重复处理。
  2. if (left <= right) 的作用

    • 当从右到左遍历完 bottom 行后,会将 left 列从下到上遍历。
    • 同理,如果在遍历 right 列之后,left 已经超过了 right(说明已经没有未遍历的列),那么就不需要再遍历 left 列。因此,先判断 left <= right 是否成立。

复杂度分析

  • 时间复杂度:O(m×n)O(m \times n)O(m×n),因为每个元素会被访问一次。
  • 空间复杂度:O(1)O(1)O(1),除了返回结果外,额外使用的空间是常数级别。

思路拓展

相关推荐
www_stdio14 分钟前
JavaScript 执行机制详解:从 V8 引擎到执行上下文
前端·javascript
我命由我1234526 分钟前
HTML - 换行标签的 3 种写法(<br>、<br/>、<br />)
前端·javascript·css·html·css3·html5·js
吃着火锅x唱着歌30 分钟前
LeetCode 2016.增量元素之间的最大差值
数据结构·算法·leetcode
icebreaker1 小时前
重新思考 weapp-tailwindcss 的未来
前端·javascript·css
涤生啊2 小时前
一键搭建 Coze 智能体对话页面:支持流式输出 + 图片直显,开发效率拉满!
javascript·html5
郝学胜-神的一滴2 小时前
计算机图形中的法线矩阵:深入理解与应用
开发语言·程序人生·线性代数·算法·机器学习·矩阵·个人开发
吃饺子不吃馅2 小时前
⚡️ Zustand 撤销重做利器:Zundo 实现原理深度解析
前端·javascript·github
元亓亓亓3 小时前
LeetCode热题100--46. 全排列--中等
算法·leetcode·职场和发展
远航_3 小时前
10 个被严重低估的 JS 特性,直接少写 500 行代码
前端·javascript
小高0073 小时前
当前端面临百万级 API 请求:从"修 CSS 的"到架构师的进化之路
前端·javascript·面试