生成最少修改次数的3阶幻方:代码逻辑问题排查求助
修复生成修改次数最少的3阶幻方代码问题
你的代码核心问题出在最小修改次数的更新逻辑写反了,导致无法正确追踪最优幻方,最终只能返回最后一个预设幻方。以下是问题分析和修复方案:
问题点拆解
- min值赋值错误:在循环判断
x < min时,你写了x = min,这相当于把当前的最小次数min赋值给临时变量x,而非把更小的x更新为新的min。这会导致min始终保持初始值9,最后只要某幻方修改次数小于9(几乎所有情况都满足),就会替换成当前循环到的幻方,最终返回最后一个。 - 二维数组浅拷贝隐患:
ms[i].slice()只能复制外层数组,内层子数组还是引用关系。虽然这里不会直接引发bug,但为避免意外修改原预设幻方,建议用深拷贝。 - 参数直接修改混淆:直接修改函数参数
arr会让逻辑不清晰,建议单独维护变量存储最优幻方。
修复后的代码
function minChange(arr) { // 所有3阶幻方的预设集合 const magicSquares = [ [[4, 3, 8], [9, 5, 1], [2, 7, 6]], [[6, 1, 8], [7, 5, 3], [2, 9, 4]], [[2, 7, 6], [9, 5, 1], [4, 3, 8]], [[2, 9, 4], [7, 5, 3], [6, 1, 8]], [[8, 1, 6], [3, 5, 7], [4, 9, 2]], [[8, 3, 4], [1, 5, 9], [6, 7, 2]], [[6, 7, 2], [1, 5, 9], [8, 3, 4]], [[4, 9, 2], [3, 5, 7], [8, 1, 6]] ]; // 计算输入数组与目标幻方的修改次数 function calculateChanges(input, target) { let count = 0; for (let i = 0; i < 3; i++) { for (let j = 0; j < 3; j++) { if (input[i][j] !== target[i][j]) { count++; } } } return count; } let minChanges = 9; // 最大可能修改次数为9 let bestMagicSquare = null; for (const square of magicSquares) { const currentChanges = calculateChanges(arr, square); // 找到修改次数更少的幻方时,更新最优记录 if (currentChanges < minChanges) { minChanges = currentChanges; // 深拷贝避免引用问题 bestMagicSquare = square.map(row => [...row]); } } return bestMagicSquare; } // 测试用例 const testArr = [[4, 9, 2], [3, 5, 7], [8, 1, 5]]; console.log(minChange(testArr));
修复说明
- 修正
minChanges的更新逻辑,确保每次找到修改次数更少的幻方时,同步更新最小次数和最优幻方。 - 使用
map(row => [...row])对二维数组进行深拷贝,彻底避免引用原预设数组的问题。 - 优化变量命名(比如
ms改为magicSquares,magic改为calculateChanges),提升代码可读性。 - 用
for...of循环遍历幻方集合,比传统for循环更简洁直观。
对于你的测试用例[[4,9,2],[3,5,7],[8,1,5]],最优幻方是[[4,9,2],[3,5,7],[8,1,6]],仅需修改最后一个元素(5→6),修改次数为1,修复后的代码会正确返回这个结果。
内容的提问来源于stack exchange,提问作者Cris Gallegos
相关产品推荐
相关产品推荐

