刷题时遇到的方形蛇阵填充问题,对于本人来说还是有点难度的,所以写了一下这篇文章帮助自己更好的理解和学习遇到的难点,希望对大家也有一定的帮助。
一、问题理解
需要在一个 n×n 方阵中按照蛇形顺序,即从右上角开始沿方阵边界顺时针依次填充1~n*n,使得每一层呈波浪形排列。这需要我们思考如何准确的填充数字,并且确保它们在方阵中的顺序与位置,同时还要考虑到溢出边界情况与填充方向的转变。
二、代码实现思路
1. 创建数组:
- 使用 Array.from 方法创建一个 n*n 的二维数组 arr ,并全部初始化为0,方便我们后续对数组的填充。
let arr = Array.from({ length: n }, () => Array(n).fill(0))
2. 定义方向数组:
我们在插入数据时,会遇到换行或者换列的情况,此时我们可以定义一个二维数组来表示右、下、左、上四个方向,在此数组中,[0,1]就表示了右上的点(这道题我们也是从右上角的点开始插入的),而[1, 0]可以看到行增加了,而列没有变,是[0,1]正下方的点,此时我们就可以通过directArr二维数组的辅助来实现换行不换列的功能,以达到向下转向的效果,[0, -1], [-1, 0]的功能也是这样,就不一一列举了。
let directArr = [[0, 1], [1, 0], [0, -1], [-1, 0]]
3. 初始化位置与方向:
对起始位置和方向进行初始化,x = 0 , y = n - 1 ,即右上角位置,方向索引 dirIndex = 0 (初始为向右)。
let x = 0, y = n - 1, dirIndex = 0
4. 循环填充数字:
- 利用for循环从 1 到 n×n 进行循环填充数字。
- 先将初始位置 arr[x][y] 填充为当前数字 num=1。
- 计算下一个位置 nextX 和 nextY ,通过当前位置加上方向数组中对应方向的偏移量(列或者行需要改变)。
- 需要判断下一个位置是否越界(超出方阵范围)或者该位置已被填充(不为 0),如果是,则更新方向索引 dirIndex = (dirIndex + 1) % 4 (取余4的原因:因为方向索引在需要转向时会加1,但是在蛇形方阵填充完毕之前,需要多次转向,为了防止方向数组溢出,需要使dirIndex在0-3之间循环) ,实现方向的切换,更换方向数组中对应的偏移量,然后重新计算下一个位置。
- 最后将 x 和 y 更新为下一个正确位置,继续循环,直到所有数字填充完毕。
for (let num = 1; num <= n * n; num++) {
arr[x][y]= num
//计算下一个位置
let nextX = x + directArr[dirIndex][0]
let nextY = y + directArr[dirIndex][1]
//判断是否溢出,以及换行
if (nextX >= n || nextX < 0 || nextY >= n || nextY < 0 || arr[nextX][nextY] !== 0) {
dirIndex = (dirIndex + 1) % 4
// 更新位置
nextX = x + directArr[dirIndex][0]
nextY = y + directArr[dirIndex][1]
}
x=nextX
y=nextY
}
最后再将结果返回即可。
三、AI刷题工具
1.功能亮点
- 协助改错与调试支持:在写代码的时候,有时候有些比如变量名拼写错误的问题不容易被发现,这时,我们就可以让AI工具协助我们进行查找并改错,减少了传统手动调试的繁琐过程。
- 思路引导与解析:在写题过程中,有时候会遇到没有思路的情况,这时AI的便利就很大的体现了出来,不用我们跑很多网站或者文章去看解析,整理思路。AI不仅提供了详细的思路引导,还给出了标准的解法,甚至还能帮我们优化代码,检查自己的思路是否合理。在此次做题过程中,因为刷算法题并不是很熟练的原因,一度没有思路,使用AI后,让我对题意有了更准确的了解,解答起来也更得心应手了。
- AI辅助学习的优势:在刷题过程中,有时我们并不会准确的记得每一个函数的功能与用法,就比如这次刷题使用到的字符填充方法,当时写题的时候根本没想起来具体用法!使用AI工具之后才更详细的了解这个方法,大大减少了查资料所耗费的时间。AI工具能帮助我们更准确具体的学习不会的难点。
2. 刷题实践
AI刷题平台的独特优势在于它不仅提供了题目和自动评测工具,更通过智能反馈、解法引导等功能帮助我们逐步提升解题能力。对于我们算法和编程学习者来说,AI刷题平台的这些功能无疑加速了知识的吸收与应用,提升了学习的效率和效果。
四、难点与解析
1. 如何创建一个指定长度的数组:
使用Array.from({ length: n }),{length:n}是一个对象,属性为length,值为n,而Array.from()则是从一个数组或者可迭代对象创建一个新的数组实例,它接收两个参数,
- 类似数组或可迭代对象:可以是数组、字符串、Set、Map 等。
- 映射函数(可选):用于对每个元素进行处理的函数。
而Array.from({ length: n })正是同时利用了对象和Array.from()的特性将对象转换为一个数组,数组的长度为
3,每个元素的值为undefined。
2. 利用fill()函数初始化二维数组:
fill 函数是 JavaScript 数组对象的一个方法,用于将数组的所有元素或部分元素填充为指定的值。fill 方法可以接受三个参数:
- value(必需):要填充到数组中的值。
- start(可选):填充的起始索引(包含),默认为
0。 - end(可选):填充的结束索引(不包含,即左闭右开),默认为数组的长度。
语法
array.fill(value, start, end)
fill方法返回修改后的数组。(注意:fill函数会修改原数组,而不是创建一个新的数组)
3. 方向控制与边界处理:
通过方向数组和巧妙的边界判断及方向切换逻辑,能够在复杂的方阵填充场景中准确控制填充路径。这种思路可应用于类似的路径规划或矩阵填充问题,提升了我对数组操作和逻辑控制的能力,为解决更复杂的问题奠定了基础。
五、总结
通过这道题的学习,不仅提高了对数组和矩阵的操作技巧,还通过不断思考方向控制和边界处理问题,增强了问题分解和动态规划的能力。AI工具的辅助作用使得我的思路更为清晰,解题过程更加高效,也让复杂的算法题变得不再那么陌生。希望这篇文章也能够帮助其他同学更好地理解并掌握蛇形填充题目的解法!