每日算法练习: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),只需要稍微修改初始化逻辑即可套用。

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

相关推荐
kkeeper~7 小时前
0基础C语言积跬步之数据在内存中的存储
c语言·数据结构·算法
wabs6669 小时前
关于贪心算法的一些自我总结【力扣45.跳跃游戏II】【灵感来源:代码随想录】
算法·贪心算法·复盘
2401_876964139 小时前
【湖北专升本】2026湖北专升本真题PDF+备考资料汇总
数据结构·人工智能·经验分享·深度学习·算法·计算机视觉
嗝o゚9 小时前
CANN GE 算子融合——融合算法与调度策略
算法·昇腾·cann·ge
小江的记录本10 小时前
【JVM虚拟机】垃圾回收GC:垃圾回收算法:标记-清除、标记-复制、标记-整理、分代收集(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·算法·安全·面试
Ulyanov11 小时前
用声明式语法重新定义Python桌面UI:QML+PySide6现代开发入门(一)
开发语言·python·算法·ui·系统仿真·雷达电子对抗仿真
数据科学小丫11 小时前
特征工程处理
人工智能·算法·机器学习
z落落12 小时前
C#参数区别
java·算法·c#
c2385612 小时前
vector(下)
数据结构·算法
z落落12 小时前
C# 冒泡排序+选择排序 + Array.Sort 自定义排序
数据结构·算法