leetcode59.螺旋矩阵II 很绕?理不清?一文给你快速理清思路

🎯 本文详细解析了LeetCode螺旋矩阵II问题的解法。通过一圈一圈填充矩阵的方式,将复杂问题分解为顶行、右列、底行、左列四步操作,每圈填充数量随圈数递减。文中清晰阐述了遍历规律与代码实现逻辑,包括如何确定起点、终点及循环次数,并特别处理了奇数阶矩阵中心元素的填充问题。附带完整Java代码示例,帮助读者理解并掌握这一经典算法题的解决思路。

📖题目📖

题目链接:leetcode.cn/problems/sp...

很多读者看到这道题没理清思路,然后就开始写代码,试来试去提交都有问题。

做这道题,首先需要找一个统一的规律,然后实现起来比较绕,对代码能力也有要求

💱找规律💱

如何填充

  • 一圈一圈来填充(第一圈是浅绿色,第二圈是浅蓝色)
  • 填充一个圈的时候,需要分为四步来操作,即分别填充圈的顶行、右列、底行、左列。假如圈是 n 行 n 列,则顶行、右列、底行、左列 分别填充 n-1 个数。
    • 如第 0 圈,是 5行5列 ,那每一步就填充 4 个数字。
    • 第一步填充 1、2、3、4
    • 第二步填充 5、6、7、8
    • 第三步填充 9、10、11、12
    • 第四步填充 13、14、15、16

从当前圈到下一圈的规律

  • 填充完一圈之后,下一步就是往里面走一圈。
  • 如果当前圈是 n 行 n 列,那往里走一圈就是 n-2 行 n-2 列。姐每往里走一圈,行数、列数都要减 2 。
    • 第 0 圈:5 行 5 列;
    • 第 1 圈:3 行 3 列;
    • 第 2 圈:1 行 1 列

💱如何遍历💱

遍历哪行哪列数据

以顶行填充为例,第 0 圈填充的第 0 行;第 1 圈填充的第 1 行。即第几圈遍历第几行,因此使用一个变量circleNum来表示当前遍历的圈数。

遍历怎么写

如何知道一个循环要怎么写,需要分别确定起点 start 和终点 end。end-start就是循环次数。那我们只要知道 start和循环次数即可

java 复制代码
for (int i = start; i < end; i++) {
}
循环次数如何确定

每一步遍历多少个数?

  • 在 5 行 5 列的矩阵填充中,第 0 圈每一步遍历 4 个数,第 1 圈遍历 2 个数,第 2 圈遍历 0 个数(第 2 圈只剩下一个数,不需要遍历处理了,最后额外处理一下就行,不理解直接看代码实现小节)。
  • 即一开始维护一个变量number=n-1,每走完一圈,number减少 2 即可
遍历起点是啥

以顶行为例,第 0 圈从 0 开始遍历,第 1 圈从 1 开始遍历。因此遍历起点是circleNum

java 复制代码
for (int j = circleNum; j < circleNum + number; j++) {
    result[circleNum][j] = ++curNum;
}

右列、底行、左列 规律也依此类推

🧑‍💻代码实现🧑‍💻

代码中 number>0 才继续循环,在 5 行 5 列矩阵中,最后的 25 是没有填充的。那怎么填充这个数字呢?

其实直接设置中间的格子就行

java 复制代码
if (curNum < n * n) {
    result[n / 2][n / 2] = n * n;
}

当然,只有 n 为单数的时候,才需要额外设置。n 为复数的时候,没有漏单的元素,如下图所示

java 复制代码
public static int[][] generateMatrix(int n) {
    int[][] result = new int[n][n];

    // 遍历次数
    int number = n - 1;
    // 走过的圈数
    int circleNum = 0;
    // 当前要填充的数字
    int curNum = 0;

    while (number > 0) {
        /// 顶行填充
        // 第一圈填充的第一行;第二圈填充的第二行
        // 因此,处理第几圈,就是遍历第几行
        for (int j = circleNum; j < circleNum + number; j++) {
            result[circleNum][j] = ++curNum;
        }

        /// 右列填充
        // 第一圈填充的最后一列(n-1);第二圈填充的倒数第二列(n-2)
        // 因此,第几圈,就是倒数第几列
        // 总结为处理 n - circleNum - 1
        for (int i = circleNum; i < circleNum + number; i++) {
            result[i][n - circleNum - 1] = ++curNum;
        }

        // 底行填充
        for (int j = circleNum; j < circleNum + number; j++) {
            result[n - circleNum - 1][n - j - 1] = ++curNum;
        }

        // 左列填充
        for (int i = circleNum; i < circleNum + number; i++) {
            result[n - i - 1][circleNum] = ++curNum;
        }

        // 没转一圈,要遍历的次数就少俩
        number -= 2;
        // 圈数 +1
        circleNum++;
    }

    // --if-- 如果剩下最后一个格子没有填,填充最后一个格子
    if (curNum < n * n) {
        result[n / 2][n / 2] = n * n;
    }

    return result;
}
相关推荐
m0_587383002 小时前
广州 24 小时自助健身房解决方案技术实现与实战指南
java·spring·小程序·架构·需求分析
mmmmath_32 小时前
LeetCode.199.二叉树的右视图
数据结构·leetcode
·云扬·2 小时前
Prompt 工程与安全:从 System 设计到注入防御
java·人工智能·安全·ai·prompt
代码不停3 小时前
自动化测试(java)
java·开发语言·selenium·自动化
行百里er3 小时前
Redis 完结篇——Redis 热点问题在 Spring Boot 项目中实战
redis·后端
高频因子挖掘机4 小时前
只取最近 60 个交易日,却每次拉全历史:量化脚本变慢的原因与改法
后端·github·api
鬼手点金5 小时前
opencode-rules 插件
java·开发语言·前端·人工智能·chrome·git·github
孟健5 小时前
从5000亿Token到83%字节匹配:AI逆向工程与重构的工程闭环实践
后端·架构·ai编程
paopaokaka_luck5 小时前
滑雪场管理系统(AI智能助手流式对话,ECharts 运营数据分析、教练、雪具与场地一体化预约,钱包支付退款、订单核销与服务评价)
java·人工智能·spring boot·网络协议·数据分析·echarts
码事漫谈6 小时前
丢得静悄悄,谈一谈 Agent 的记忆是怎么没的
后端