每日算法练习:LeetCode 54. 螺旋矩阵 ✅

大家好,我是你们的算法小伙伴。今天我们来练习一道矩阵模拟 的经典中等题 ------LeetCode 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

解题思路

核心思路:按层模拟,边界收缩

螺旋遍历的本质是按顺序绕圈

  1. 从左到右(顶行)
  2. 从上到下(右列)
  3. 从右到左(底行)
  4. 从下到上(左列)

走完一圈后,收缩边界(上边界 + 1,下边界 - 1,左边界 + 1,右边界 - 1),继续遍历内层,直到所有元素都被访问。

最优解法:四边界 + 循环判定

核心变量(四个边界):

  • top:上边界(行号,初始 0)
  • bottom:下边界(行号,初始matrix.length-1
  • left:左边界(列号,初始 0)
  • right:右边界(列号,初始matrix[0].length-1

逻辑步骤:

  1. 遍历顶行:从 leftright,遍历完 top++
  2. 遍历右列:从 topbottom,遍历完 right--
  3. 遍历底行:从 rightleft,遍历完 bottom--
  4. 遍历左列:从 bottomtop,遍历完 left++
  5. 循环终止 :当 top > bottomleft > right 时,停止遍历。

代码实现

复制代码
class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> res = new ArrayList<>();
        if (matrix == null || matrix.length == 0) {
            return res;
        }

        // 1. 定义四个边界
        int top = 0;
        int bottom = matrix.length - 1;
        int left = 0;
        int right = matrix[0].length - 1;

        // 2. 循环遍历,直到边界相遇
        while (top <= bottom && left <= right) {
            // ① 从左到右:遍历顶行
            for (int i = left; i <= right; i++) {
                res.add(matrix[top][i]);
            }
            top++; // 上边界下移

            // ② 从上到下:遍历右列
            // 需判断是否还有行可遍历(防止只有一行的情况)
            if (top > bottom) break;
            for (int i = top; i <= bottom; i++) {
                res.add(matrix[i][right]);
            }
            right--; // 右边界左移

            // ③ 从右到左:遍历底行
            // 需判断是否还有列可遍历(防止只有一列的情况)
            if (left > right) break;
            for (int i = right; i >= left; i--) {
                res.add(matrix[bottom][i]);
            }
            bottom--; // 下边界上移

            // ④ 从下到上:遍历左列
            if (top > bottom) break;
            for (int i = bottom; i >= top; i--) {
                res.add(matrix[i][left]);
            }
            left++; // 左边界右移
        }

        return res;
    }
}

代码详解

1. 边界初始化

  • top = 0:初始指向第一行。
  • bottom = matrix.length - 1:初始指向最后一行。
  • left = 0:初始指向第一列。
  • right = matrix[0].length - 1:初始指向最后一列。

2. 主循环

while (top <= bottom && left <= right):保证每次循环都是一个有效的矩形区域。

3. 四个方向遍历(重点!)

① 从左到右(顶行)
  • 遍历范围:[top][left][top][right]
  • 遍历结束后:top++(这一行已经走完,下移一层)
② 从上到下(右列)
  • 必须先判断 top > bottom
    • 比如矩阵是 [1,2,3](一行),遍历完顶行后 top=1,此时 top > bottom,直接退出,避免重复添加。
  • 遍历范围:[top][right][bottom][right]
  • 遍历结束后:right--(这一列已经走完,左移一层)
③ 从右到左(底行)
  • 必须先判断 left > right
    • 比如矩阵是 [[1],[2],[3]](一列),上两步走完后 right=0,此时 left > right,直接退出。
  • 遍历范围:[bottom][right][bottom][left]
  • 遍历结束后:bottom--(这一行已经走完,上移一层)
④ 从下到上(左列)
  • 必须先判断 top > bottom:防止行越界。
  • 遍历范围:[bottom][left][top][left]
  • 遍历结束后:left++(这一列已经走完,右移一层)

4. 防越界判断(面试加分项!)

在遍历右列、底行、左列之前,都要再次判断边界是否交叉。

  • 例如:如果矩阵只有一行(m=1),遍历完顶行 后,top++ 会导致 top > bottom,后续的循环直接跳过,不会出错。

示例模拟

示例 1 [[1,2,3],[4,5,6],[7,8,9]] 为例:

  1. 初始状态top=0, bottom=2, left=0, right=2
    • 顶行(0 行):添加 1,2,3top=1
    • 右列(2 列):添加 6,9right=1
    • 底行(2 行):添加 8,7bottom=1
    • 左列(0 列):添加 4left=1
  2. 当前状态top=1, bottom=1, left=1, right=1(中心只剩一个 5
    • 进入循环,top<=bottomleft<=right 成立。
    • 顶行(1 行):添加 5top=2
    • 此时判断 top > bottom (2>1),break,循环结束。
  3. 最终结果[1,2,3,6,9,8,7,4,5],完美匹配!

复杂度分析

指标 复杂度 说明
时间复杂度 O(mn) 每个元素只遍历一次,遍历次数等于矩阵元素总数
空间复杂度 O(1) 除了结果列表,只使用了常数个变量(边界)

高频易错点总结

  1. 忘记判断边界 :遍历右列、底行、左列前,必须加 if 判断,否则会出现元素重复数组越界错误。
  2. 方向顺序错误 :必须严格遵循左→右 → 上→下 → 右→左 → 下→上的顺序。
  3. 边界更新时机 :先遍历,后更新边界(top++ 等操作必须在遍历完那一圈之后做)。
  4. 矩阵形状
    • 处理 1xN (一行)或 Nx1 (一列)的矩阵时,代码能自动处理,因为边界判断会触发 break

总结

这道题的核心是 **「边界收缩」**。

  • 不要死记硬背,只要记住:走一圈,四个方向各走一遍,然后把包围圈往里缩一点,继续走。
  • 这道题的代码模板非常通用,面试中如果遇到螺旋矩阵 II(LeetCode 59),只需要稍微修改初始化逻辑即可套用。

今天的每日算法练习就到这里,我们明天再见!👋

相关推荐
xrgs_shz7 分钟前
基于轻量化浅层卷积神经网络的手写数字识别
算法·matlab·cnn
计算机安禾18 分钟前
【计算机网络】第10篇:距离矢量路由算法——Bellman-Ford方程与RIP协议的特性分析
计算机网络·算法
机器学习之心27 分钟前
基于开普勒优化算法(KOA)优化CNN-BiGRU-Attention混合网络的时间序列预测模型,MATLAB代码
算法·时间序列预测模型·开普勒优化算法
Java成神之路-1 小时前
【LeetCode 刷题笔记】367.有效的完全平方数 | 二分查找经典刷题题解
算法·leetcode
一切皆是因缘际会9 小时前
从概率拟合到内生心智:2026 下一代 AI 架构演进与落地实践
人工智能·深度学习·算法·架构
Java成神之路-9 小时前
【LeetCode 刷题笔记】34. 在排序数组中查找元素的第一个和最后一个位置 | 二分查找经典刷题题解
算法·leetcode
不忘不弃9 小时前
用BFS方法求解平分汽油问题
算法·宽度优先
AI科技星9 小时前
全域数学·72分册·射影原本 无穷维射影几何卷细化子目录【乖乖数学】
人工智能·线性代数·算法·机器学习·数学建模·数据挖掘·量子计算
风落无尘9 小时前
《智能重生:从垃圾堆到AI工程师》——第四章 变化的艺术
人工智能·线性代数·算法
JAVA面经实录9179 小时前
计算机基础(完整版·超详细可背诵)
java·linux·数据结构·算法