青训营字节 MarsCode 技术训练营第一课——题解 | 豆包MarsCode AI 刷题

159 阅读3分钟

题目链接:www.marscode.cn/practice/9e…

蛇形填充n阶方阵

题目:小U面临一个有趣的任务:在一个 n×n 的方阵中填入1到n*n这些数字,并要求按照蛇形顺序从右上角开始,沿着方阵的边界顺时针进行填充。蛇形填充的特殊排列方式使得每一层数字呈现出波浪形的排列方式。 例如,当 n=4时,方阵应如下所示:

[ 10 11 12 1

9 16 13 2

8 15 14 3

7 6 5 4  ]

题目分析:

我们需要在一个n*n的方阵中,按照蛇形顺序从右上角开始,沿着方阵的边界顺时针进行填充。蛇形填充的特殊排列方式使得每一层数字呈现出波浪形的排列方式。

初步尝试:从右上角开始填充,然后转向,尝试后发现无法解决后续转向问题,重新开始思考。

题目图解:

在填充数字过程中,需要不断地转换填充方向。

80e1cca542a1e88b0dfd2fee6aedc899.png

算法解决:

算法核心在于模拟蛇形实现数组填充。其中关键点在于方向控制、边界处理、蛇形填充等步骤。

首先我们定义一个n*n的数组用于存储这些数字。

定义填充方向:我们需要定义四个方向:上、下、左、右。可以使用一个方向数组directions来表示这四个方向的移动。

填充数字:题目规定从右上角开始,按照顺时针方向填充数字。每次填充一个数字后,根据当前方向移动到下一个位置。

边界处理:当遇到边界或者已经填充过的位置时,需要改变方向,如向左、向上。

蛇形填充:在每一层的填充过程中,需要交替改变填充方向,形成波浪形。

关键代码实现:

   `int[][] matrix = new int[n][n];
    int num = 1;
    int x = 0, y = n - 1; // 从右上角开始
    int[][] directions = {{1, 0}, {0, -1}, {-1, 0}, {0, 1}}; // 方向数组:下、左、上、右
    int dirIndex = 0; // 当前方向的索引`

在这段代码中首先定义了存储数组matrix,根据题目要求从右上角开始填充。并定义了我们的方向数组directions,根据题目示例可以得到首先向下进行填充,据此对方向数组进行赋值。 ` while (num <= n * n) { matrix[x][y] = num++; // 填充当前单元格 int nextX = x + directions[dirIndex][0]; // 计算下一个单元格的位置 int nextY = y + directions[dirIndex][1];

        // 如果下一个单元格越界或者已经被填充,则改变方向
        if (nextX < 0 || nextX >= n || nextY < 0 || nextY >= n || matrix[nextX][nextY] != 0) {
            dirIndex = (dirIndex + 1) % 4; // 循环改变方向
            nextX = x + directions[dirIndex][0]; // 重新计算下一个单元格的位置
            nextY = y + directions[dirIndex][1];
        }

        x = nextX; // 更新当前位置
        y = nextY;
    }`

数组填充值从1开始,因此每次填充时num++,同时通过x + directions[dirIndex][0]和y + directions[dirIndex][1]计算下一个单元格的位置,在填充过程中要注意边界问题,因此在这里用if语句进行判断。。

dirIndex = (dirIndex + 1) % 4 是非常关键的一步,循环改变方向,实现向左、向上等转变,然后更新当前位置,继续填充,从而实现蛇形填充我们的数组。

在本题目中需要注意的一点是从右上角向下开始第一次填充

学习方法:

在刷题过程中尽量先自己尝试写代码解决,遇到运行部分案例不通过或者没有思路时,可以让旁边的AI帮你检查编辑框的代码或者给你提供思路,但最重要的是对代码要有自己的思考,在学习AI的解题思路后,实现自己能够独立再次解决题目,同时遇到难题时可以多次复习,培养自己的思维模式。建议的刷题路径是由简到难,逐步提升,不要想着一口吃成个胖子。