💥LeetCode 59 题螺旋矩阵 II:代码详解与思路剖析

124 阅读4分钟

家人们谁懂啊!LeetCode59 题螺旋矩阵 II,被我轻松拿捏

家人们,今天来挑战一道超有意思的 LeetCode 题,螺旋矩阵 II。这题就像一个神秘的数字迷宫,咱们得把 1 到 这些数字,按照顺时针螺旋的方式,整齐地放进一个 的矩阵里😎。别慌,看我用代码 “降维打击”,带你轻松通关!

题目描述

给你一个正整数 ,生成一个包含 1 到 所有元素,且元素按顺时针顺序螺旋排列的 正方形矩阵 。

这就好比让你把 1 到 这些数字,像贪吃蛇一样,沿着矩阵的 “墙壁”,顺时针一圈一圈地排好队,是不是很有画面感?

代码实现

class Solution {
    public int[][] generateMatrix(int n) {
        int[][] ret = new int[n][n];
        int circleNum = (n + 1) / 2;
        int num = 1;
        for (int i = 0; i < circleNum; i++) {
            for (int j = i; j < n - i; j++) {
                ret[i][j] = num++;
            }
            if ((n & 1) == 1 && i == circleNum - 1) {
                continue;
            }
            for (int j = i + 1; j < n - i - 1; j++) {
                ret[j][n - i - 1] = num++;
            }
            for (int j = n - i - 1; j >= i; j--) {
                ret[n - i - 1][j] = num++;
            }
            for (int j = n - i - 2; j > i; j--) {
                ret[j][i] = num++;
            }
        }
        return ret;
    }
}

接下来,咱们就一步步拆解这段代码,看看它是怎么 “玩转” 这个数字迷宫的。

代码思路分析

1. 初始化矩阵

int[][] ret = new int[n][n];

这一步就像是搭积木,先搭好一个 的 “空房子”,也就是一个二维数组ret,用来存放我们即将填入的数字。这可是整个数字迷宫的框架,必须得先安排好。

2. 确定循环圈数

int circleNum = (n + 1) / 2;
int num = 1;

这里的circleNum就是我们要绕着这个 “空房子” 画圈的次数。为啥是(n + 1) / 2呢?这就好比切蛋糕,当n是奇数的时候,最中间那一块蛋糕(也就是最中间的那个数字)只需要分一次,这个公式就能完美适配奇数和偶数的情况,主打一个 “雨露均沾”。同时,我们初始化要填入的数字num为 1,这就是我们 “贪吃蛇” 旅程的起点。

3. 按圈填充元素

for (int i = 0; i < circleNum; i++) {

这个外层循环就像是我们开启了一圈又一圈的 “贪吃蛇大作战”,每一圈都要按照顺时针方向,把数字依次填到矩阵的四条边上。

填充上边
for (int j = i; j < n - i; j++) {
    ret[i][j] = num++;
}

这一步就像是贪吃蛇在矩阵的上边缘 “横行霸道”,从左到右依次把数字填进去。i就像是贪吃蛇的 “行坐标”,固定在当前圈的起始行,j从i开始,一直到n - i - 1结束,每走一步,就把num的值填进去,然后num自增,主打一个 “步步为营”。

特殊情况处理(奇数阶矩阵最中间元素)
if ((n & 1) == 1 && i == circleNum - 1) {
    continue;
}

当n是奇数,并且我们已经到了最后一圈的时候,最中间的那个数字已经在上边填充的时候被 “拿下” 了,这时候就直接跳过后面三条边的填充,不然就会 “重复劳动”,主打一个 “不做无用功”。

填充右边
for (int j = i + 1; j < n - i - 1; j++) {
    ret[j][n - i - 1] = num++;
}

贪吃蛇吃完了上边,就开始沿着矩阵的右边 “垂直降落”。起始行索引为i + 1,结束行索引为n - i - 2,列索引固定为n - i - 1,继续把递增的数字填进去,这就是 “一路向下” 的节奏。

填充下边
for (int j = n - i - 1; j >= i; j--) {
    ret[n - i - 1][j] = num++;
}

吃完右边,贪吃蛇又来到了下边,开始从右到左 “横扫千军”。行索引固定为n - i - 1,列索引从n - i - 1到i,依次把数字填好,这就是 “横向冲刺”。

填充左边
for (int j = n - i - 2; j > i; j--) {
    ret[j][i] = num++;
}

最后,贪吃蛇沿着左边 “逆流而上”,起始行索引为n - i - 2,结束行索引为i + 1,列索引固定为i,完成一圈的填充。这一圈下来,就像是给矩阵穿上了一层 “数字铠甲”。

4. 返回结果

return ret;

当我们把所有的数字都填好之后,就把这个 “全副武装” 的矩阵ret返回,大功告成!家人们,这道题是不是也不过如此嘛,轻松拿捏🤏!

通过这样的步骤,我们就成功解开了螺旋矩阵 II 的谜题。以后再遇到类似的题目,咱们就可以 “以不变应万变”,轻松应对啦!家人们,一起加油,向着更多的算法难题进军,奥利给💪!