algorighm/recursion/n皇后.js

104 lines
2.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 解决N皇后问题
* @param {number} n - 棋盘大小和皇后数量
* @return {string[][]} - 所有可能的解决方案
*/
function solveNQueens(n) {
const result = [];
// 创建一个表示棋盘的数组,初始化为空
const board = Array(n).fill().map(() => Array(n).fill('.'));
// 开始回溯
backtrack(0);
return result;
/**
* 回溯函数,尝试在每一行放置皇后
* @param {number} row - 当前处理的行
*/
function backtrack(row) {
// 如果已经放置了n个皇后找到一个解决方案
if (row === n) {
// 将当前棋盘状态转换为所需的格式并添加到结果中
const solution = board.map((row) => row.join(''));
result.push(solution);
return;
}
// 尝试在当前行的每一列放置皇后
for (let col = 0; col < n; col++) {
// 检查当前位置是否可以放置皇后
if (isValid(row, col)) {
// 放置皇后
board[row][col] = 'Q';
// 递归到下一行
backtrack(row + 1);
// 回溯,移除皇后
board[row][col] = '.';
}
}
}
/**
* 检查在[row, col]位置放置皇后是否有效
* @param {number} row - 行索引
* @param {number} col - 列索引
* @return {boolean} - 如果位置有效返回true否则返回false
*/
function isValid(row, col) {
// 检查同一列是否有皇后
for (let i = 0; i < row; i++) {
if (board[i][col] === 'Q') {
return false;
}
}
// 检查左上对角线是否有皇后
for (let i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
if (board[i][j] === 'Q') {
return false;
}
}
// 检查右上对角线是否有皇后
for (let i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
if (board[i][j] === 'Q') {
return false;
}
}
return true;
}
}
/**
* 打印棋盘
* @param {string[]} board - 表示棋盘的字符串数组
*/
function printBoard(board) {
for (const row of board) {
console.log(row);
}
console.log('---');
}
// 测试代码
function testNQueens(n) {
console.log(`求解${n}皇后问题:`);
const solutions = solveNQueens(n);
console.log(`找到${solutions.length}个解决方案`);
// 打印前3个解决方案
for (let i = 0; i < Math.min(3, solutions.length); i++) {
console.log(`解决方案 ${i + 1}:`);
printBoard(solutions[i]);
}
}
// 测试8皇后问题
testNQueens(8);