N皇后问题JavaScript代码中result变量未被正确修改是什么原因?
问题原因
这是JavaScript引用类型的特性导致的:
- 你定义的
buffer是数组,属于引用类型,变量存储的是数组的内存地址,不是数组本身的内容 - 你调用
result.push(buffer)时,存入result的是buffer的内存地址,而非当前数组内容的快照 - 后续回溯流程中你修改
buffer的元素值时,所有已经存入result的引用指向的内容都会同步被修改 - 当遍历全部结束后,
buffer的所有元素都被重置为'-',所以最终返回的result里所有元素都是全'-'的数组 - 你在递归终止分支里打印时看到的是当时
buffer的瞬时值,所以看起来是正确的,不影响后续被修改的结果
修复方案
只需要修改存入result的那一行代码,把当前buffer的浅拷贝存入即可(数组元素都是基础类型,浅拷贝就足够):
把原代码中的
result.push(buffer);
替换为以下任意一种写法即可:
// 展开运算符拷贝 result.push([...buffer]); // slice方法拷贝 result.push(buffer.slice()); // Array.from拷贝 result.push(Array.from(buffer));
修改后完整代码
function solveNQueens(n) { let result = []; let buffer = Array(n).fill('-'); function solve(bufferIndexRow) { if (bufferIndexRow === n) { // 存入当前buffer的拷贝,避免后续修改影响已保存的结果 result.push([...buffer]); console.log('FOUND ONE SOLUTION'); return; } for (let column = 0; column < n; column++) { buffer[bufferIndexRow] = column; if (isValid(bufferIndexRow, column)) { solve(bufferIndexRow + 1); } buffer[bufferIndexRow] = '-' } } function isValid(row, col) { for(let i = 0; i< row; i++) { if(buffer[i] == col || Math.abs(i - row) == Math.abs(buffer[i]- col)) return false; } return true; } solve(0); return result; } // 测试4皇后,输出正确结果:[[1, 3, 0, 2], [2, 0, 3, 1]] console.log(solveNQueens(4));
内容的提问来源于stack exchange,提问作者ehehe341
相关产品推荐
相关产品推荐

