【矩阵专题】Leetcode54.螺旋矩阵(Hot100)

螺旋矩阵

一、题目描述

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

示例:

输入:

java 复制代码
matrix = [
 [1, 2, 3],
 [4, 5, 6],
 [7, 8, 9]
]

输出:

复制代码
[1, 2, 3, 6, 9, 8, 7, 4, 5]

二、解题思路:模拟"画圈圈"的过程

这道题最直接的做法是模拟"从外到内逐层遍历"的过程,也就是四个方向依次遍历

  • 从左到右遍历顶部行
  • 从上到下遍历右侧列
  • 从右到左遍历底部行
  • 从下到上遍历左侧列

然后不断地收缩边界,直到遍历完整个矩阵。


三、图解说明

如下图所示(以 3x3 矩阵为例):

复制代码
[ 1 → 2 → 3 ]
[ ↓       ↓ ]
[ 4       6 ]
[ ↓       ↑ ]
[ 7 ← 8 ← 9 ]

我们用四个变量控制边界:

  • left:左边界
  • right:右边界
  • top:上边界
  • bottom:下边界

每遍历完一圈,就收缩对应边界,直到 left > righttop > bottom


四、Java 代码实现

java 复制代码
class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        int left = 0;
        int right = matrix[0].length - 1;
        int top = 0;
        int bottom = matrix.length - 1;

        List<Integer> ans = new ArrayList<>();

        while (left <= right && top <= bottom) {
            // 从左到右
            for (int i = left; i <= right; i++) {
                ans.add(matrix[top][i]);
            }
            top++; // 上边界下移

            // 从上到下
            for (int i = top; i <= bottom; i++) {
                ans.add(matrix[i][right]);
            }
            right--; // 右边界左移

            // 从右到左(确保当前还有未遍历的行)
            if (top <= bottom) {
                for (int i = right; i >= left; i--) {
                    ans.add(matrix[bottom][i]);
                }
                bottom--; // 下边界上移
            }

            // 从下到上(确保当前还有未遍历的列)
            if (left <= right) {
                for (int i = bottom; i >= top; i--) {
                    ans.add(matrix[i][left]);
                }
                left++; // 左边界右移
            }
        }

        return ans;
    }
}

五、特别说明:两个 if 判断的作用

这两个判断是避免重复遍历或越界的关键。

if (top <= bottom) 的作用:

在执行"从右向左遍历"前,需要确保还有剩余的未访问行

比如只有一行时,从左到右遍历后,top++,就可能已经超过 bottom,这时就不能再从右往左遍历了。

if (left <= right) 的作用:

在执行"从下向上遍历"前,需要确保还有剩余的未访问列

同理,如果只剩下一列,执行完"从上到下"后,right-- 可能已经小于 left,就不能再从下向上了。


六、复杂度分析

  • 时间复杂度: O(m * n)
    每个元素都被访问一次。
  • 空间复杂度: O(1)(不计输出结果所占空间)
相关推荐
董董灿是个攻城狮5 小时前
AI视觉连载8:传统 CV 之边缘检测
算法
怒放吧德德7 小时前
Netty 4.2 入门指南:从概念到第一个程序
java·后端·netty
雨中飘荡的记忆9 小时前
大流量下库存扣减的数据库瓶颈:Redis分片缓存解决方案
java·redis·后端
心之语歌11 小时前
基于注解+拦截器的API动态路由实现方案
java·后端
华仔啊12 小时前
Stream 代码越写越难看?JDFrame 让 Java 逻辑回归优雅
java·后端
ray_liang12 小时前
用六边形架构与整洁架构对比是伪命题?
java·架构
AI软著研究员12 小时前
程序员必看:软著不是“面子工程”,是代码的“法律保险”
算法
FunnySaltyFish13 小时前
什么?Compose 把 GapBuffer 换成了 LinkBuffer?
算法·kotlin·android jetpack
Ray Liang14 小时前
用六边形架构与整洁架构对比是伪命题?
java·python·c#·架构设计
颜酱14 小时前
理解二叉树最近公共祖先(LCA):从基础到变种解析
javascript·后端·算法