青训营X豆包MarsCode 技术训练营2| 豆包MarsCode AI 刷题

50 阅读5分钟

题目解析

思路

这道蛇形方阵填充的题目,核心思路在于模拟按照特定规则在方阵中依次填充数字的过程。从方阵的右上角开始,依据右、下、左、上这四个顺时针方向,沿着方阵边界不断循环进行填充,每填充一个数字,就要判断下一个位置是否越界或者已经被填充过了,如果出现这种情况,那就顺时针切换方向,再确定新的填充位置,如此反复,直到把从 1 到  的所有数字都填充到方阵中为止。

例如,当  时,最开始在右上角(第 0 行,第 3 列)放置数字 1,然后按照右方向去尝试放置下一个数字,发现没有越界等问题就放置数字 2,接着继续按照这个方向走,当走到边界或者碰到已填充的单元格时,就按照顺时针顺序切换到向下的方向继续填充,就这样一层一层、一个数字一个数字地完成整个方阵的填充,最终得到符合要求的蛇形方阵。

public static int[][] solution(int n) {
int[][] matrix = new int[n][n]; 
int num = 1; 
// 定义四个方向:右、下、左、上 
int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; 
int row = 0, col = n - 1; // 从右上角开始 
int currentDirection = 0; // 方向索引 
// 循环填充矩阵
for (int i = 0; i < n * n; i++) {
matrix[row][col] = num++; // 填充当前数字 、
// 计算下一个位置 
int nextRow = row + directions[currentDirection][0];
int nextCol = col + directions[currentDirection][1]; 
// 检查边界条件,如果越界或碰到已填充的单元格,切换方向 
if (nextRow < 0 || nextRow >= n || nextCol < 0 || nextCol >= n || matrix[nextRow][nextCol] != 0) { 
currentDirection = (currentDirection + 1) % 4; // 顺时针切换方向 
nextRow = row + directions[currentDirection][0]; 
nextCol = col + directions[currentDirection][1]; } 
// 移动到下一个位置 
row = nextRow; 
col = nextCol;
}
return matrix; } 
public static void main(String[] args) { 
// 测试用例 
int n1 = 4;
int[][] result1 = solution(n1); System.out.println("n = " + n1); 
for (int[] row : result1) {
System.out.println(Arrays.toString(row));
}
int n2 = 5;
int[][] result2 = solution(n2); 
System.out.println("\nn = " + n2);
for (int[] row : result2) { 
System.out.println(Arrays.toString(row));
} 
int n3 = 3; 
int[][] result3 = solution(n3); 
System.out.println("\nn = " + n3); 
for (int[] row : result3) { 
System.out.println(Arrays.toString(row));
}
}
}

代码详解

首先来看代码部分,在 solution 方法里,先是创建了一个  大小的二维数组 matrix 用于存放方阵中的数字,同时初始化了一个变量 num 为 1,用来记录当前要填充的数字。接着定义了一个二维数组 directions ,它里面存储了四个方向的坐标偏移量,分别对应右、下、左、上,这就巧妙地把方向这个抽象概念转化为了代码中可以直接用于计算位置变化的数值表示。

然后设定起始位置 row = 0 ,col = n - 1 ,也就是从方阵的右上角开始,并且初始化方向索引 currentDirection = 0 表示最开始的方向是向右。在循环填充的 for 循环中,先把当前数字填充到 matrix 数组对应的位置,接着通过当前位置加上对应方向的坐标偏移量来计算下一个位置的坐标。

关键的一步在于边界条件判断,当计算出的下一个位置出现 nextRow < 0 (超出上边界)、nextRow >= n (超出下边界)、nextCol < 0 (超出左边界)、nextCol >= n (超出右边界)或者该位置已经被填充过(matrix[nextRow][nextCol]!= 0 )这些情况时,就通过 (currentDirection + 1) % 4 来顺时针切换方向,然后重新计算下一个位置坐标,最后将当前位置更新为新的位置,继续循环填充,直到把所有数字都填充完毕,最后返回填充好的方阵 matrix 。

在 main 方法中,则是给出了几个不同  值的测试样例,通过调用 solution 方法得到结果,并且将方阵按行输出展示,方便我们直观地验证代码输出是否符合预期要求,这种测试方式能有效帮我们发现代码逻辑在不同规模方阵填充上可能存在的问题。

知识总结

通过刷这道题,我们能总结出不少重要知识点以及加深对相关概念的理解。

一方面是对二维数组的操作有了更深入的掌握。二维数组在编程中常用来表示矩阵、表格等形式的数据结构,在本题里它就是存储方阵数字的关键容器。我们不仅要学会创建合适大小的二维数组,还要清楚如何准确地通过行和列的索引去访问、修改其中的元素,这对于处理很多涉及到平面布局的数据问题是非常基础且重要的技能。

另一方面是对坐标变换和边界条件处理的认识提升。根据不同方向去计算下一个位置坐标,并且依据边界情况来合理调整方向,这体现了编程中处理空间位置变化以及应对特殊情况的思路。在实际的编程场景里,比如游戏开发中角色的移动、地图元素的遍历等都会涉及到类似的坐标和边界处理逻辑,所以理解好这部分内容能为解决更复杂的相关问题打下基础。

对于入门的同学,我有以下学习建议。首先要把二维数组的基本语法知识学扎实,比如数组的声明、初始化、元素的访问方式等,可以通过简单的练习,像创建不同大小的二维数组并手动填充、输出元素等操作来加深理解。然后对于坐标变换和边界条件处理,要多去分析一些类似的、有规律的移动或者填充问题,尝试自己在纸上画出步骤和情况,再将其转化为代码逻辑,这样能更好地培养逻辑思维和代码实现能力,而且在遇到问题时,不要急于看答案,要先自己思考可能出现问题的地方,逐步调试代码去找到解决办法。