/**
* @param {number} n
* @return {string[][]}
*/
let solveNQueens = function (n) {
let res = []
// 已摆放皇后的的列下标
let columns = []
// 已摆放皇后的对角线1下标 左下 -> 右上
// 计算某个坐标是否在这个对角线的方式是「行下标 + 列下标」是否相等
let dia1 = []
// 已摆放皇后的对角线2下标 左上 -> 右下
// 计算某个坐标是否在这个对角线的方式是「行下标 - 列下标」是否相等
let dia2 = []
// 尝试在一个n皇后问题中 摆放第index行内的皇后位置
let putQueen = (rowIndex, row) => {
if (rowIndex === n) {
// res.push(generateBoard(row))
res.push(row)
return
}
// 尝试摆第index行的皇后 尝试[0, n-1]列
for (let columnIndex = 0; columnIndex < n; columnIndex++) {
// 在列上不冲突
let columnNotConflict = !columns[columnIndex]
// 在对角线1上不冲突
let dia1NotConflict = !dia1[rowIndex + columnIndex]
// 在对角线2上不冲突
let dia2NotConflict = !dia2[rowIndex - columnIndex]
if (columnNotConflict && dia1NotConflict && dia2NotConflict) {
columns[columnIndex] = true
dia1[rowIndex + columnIndex] = true
dia2[rowIndex - columnIndex] = true
putQueen(rowIndex + 1, row.concat(columnIndex))
columns[columnIndex] = false
dia1[rowIndex + columnIndex] = false
dia2[rowIndex - columnIndex] = false
}
}
}
putQueen(0, [])
return res
}
function generateBoard(row) {
let n = row.length
let res = []
// 每一行进行循环
for (let y = 0; y < n; y++) {
let cur = ""
// 每一列进行循环
for (let x = 0; x < n; x++) {
// 分支结构
// 分析for内部的逻辑结构需要注意的问题:
// 1. 如果只是一层for循环,那么我们只需要关注哪些变量是不变的,哪些变量是经常变化的量,也就是用于循环的变量,
// 这个变量经常变化,所以是我们的重点关注对象
// 2. 如果两层for循环,那么变化的变量会有两个,越往里层for循环的变量,变化越明显,因此,我们在分析的需要
// 先"按住"一个变量,然后据此进行分析内层for循环,分析好之后,在松开外层变量,进行下一轮循环分析
if (x === row[y]) cur += "Q"
else cur += "."
}
res.push(cur)
}
return res
}
console.log(solveNQueens(4))