52. N皇后 II
x 轴 在右边、 y 轴在下边
因为是一行一行遍历, 所以不需要 rows[] 这样的行 只需要维护一个 cols 的列
pie y = -x => x + y = c
na y = x => x - y = c
var totalNQueens = function(n) {
let res = 0
const cols = new Set()
const pie = new Set() // x + y
const na = new Set() // x - y
const dfs = (n, row) => {
if (row == n) {
res++
return
}
for (let col = 0; col < n; col++) {
if (cols.has(col) || pie.has(row + col) || na.has(row - col)) continue
cols.add(col)
pie.add(row + col)
na.add(row - col)
dfs(n, row + 1)
cols.delete(col)
pie.delete(row + col)
na.delete(row - col)
}
}
dfs(n, 0)
return res
};
基于位运算的回溯
一开始 如 col 为 1010 表示 第一位和第三位已经放置元素了 并且与 pie | na 或之后 取反 表示第二位和第四位可以放元素 可是这时候前面有许多的1 如 11110101 这时需去除
(1 << n) - 1 00001111 只留下最后四位
var totalNQueens = function(n) {
let res = 0
const dfs = (row, col, pie, na) => {
if (row == n) {
res++
return
}
// 得到可以放位置的 bits
let bits = (~(col | pie | na)) & ((1 << n) - 1)
while (bits) {
// 得到最后的 1 的位置
const p = bits & -bits
// col | p 更新列,表示这个列已经占据一个皇后。向下走一行后,撇捺要往左右移动一位
dfs(row + 1, col | p, (pie | p) << 1, (na | p) >> 1)
// 去掉最后的 1
bits &= bits - 1
}
}
dfs(0, 0, 0, 0)
return res
};
51. N 皇后
var solveNQueens = function (n) {
const res = []
const cols = new Set()
const pie = new Set() // x + y
const na = new Set() // x - y
const dfs = (n, row, cur_state) => {
if (row == n) {
res.push(cur_state)
return
}
for (let col = 0; col < n; col++) {
if (cols.has(col) || pie.has(row + col) || na.has(row - col)) continue
cols.add(col)
pie.add(row + col)
na.add(row - col)
dfs(n, row + 1, cur_state + col)
cols.delete(col)
pie.delete(row + col)
na.delete(row - col)
}
}
dfs(n, 0, [])
const _generate_result = (n) => {
const borads = []
for (const r of res) {
const borad = []
for (const i of r) {
borad.push(".".repeat(i) + "Q" + ".".repeat(n - i - 1))
}
borads.push(borad)
}
return borads
}
return _generate_result(n)
};
基于位运算的回溯
var solveNQueens = function (n) {
const res = new Set()
const dfs = (row, col, pie, na, cur_state) => {
if (row == n) {
res.add(cur_state)
return
}
// 得到可以放皇后的位置(0 表示没有皇后放置),取反为 1 表示可以放置皇后 &去掉前面冗余的数字
let bits = (~(col | pie | na)) & ((1 << n) - 1)
while (bits) {
// 得到最后的 1 的位置
const p = bits & -bits
// log2^n = Math.log(n) / Math.log(2) 得到具体的位数
const Qcol = Math.log((col | p) - col) / Math.log(2)
dfs(row + 1, col | p, (pie | p) << 1, (na | p) >> 1, cur_state + Qcol)
// 去掉最后的 1
bits &= bits - 1
}
}
dfs(0, 0, 0, 0, [])
const _generate_result = (n) => {
const borads = []
for (const r of res) {
const borad = []
for (const i of r) {
borad.push(".".repeat(n - i - 1) + "Q" + ".".repeat(i))
}
borads.push(borad)
}
return borads
}
return _generate_result(n)
};