/**
*
* @param n int整型 the n
* @return int整型
*/
// 回溯+剪枝
function Nqueen( n ) {
// write code here
let ans = [];
const backTrack = (arr) => {
if(arr.length === n){// 设置递归条件,同时arr.length==n说明所有**行**都找到了放置皇后的位置
//初始化所有行列的位置并初始化棋盘
let temp = new Array(n).fill(0).map(_=>new Array(n).fill('.'));
let ele = arr.map((e,i) => {
temp[i][e] = 'Q';// 放置皇后的位置
return temp[i].join('')// 将数组["Q",".",".","."]转换为[Q...]
})
ans.push(ele);// 添加答案
return;
}
for(let i=0;i < n;i++){
if(arr.indexOf(i) < 0){
let flag = true;
let cur = arr.length;
// 判断当前**列**位置是否被使用和
// 此位置是否与之前的保存的皇后位置构成对角线
for(let j= 1;cur -j >=0;j++){
if(arr[cur -j] === i - j) flag = false;
}
for(let j=1;cur-j>=0&&i+j<=n;j++){
if(arr[cur -j]===i+j) flag = false;
}
flag && backTrack(arr.concat(i));// 递归,寻找下一**行**的皇后位置
}
}
}
backTrack([])
return ans.length
}
module.exports = {
Nqueen : Nqueen
};
/**
*
* @param n int整型 the n
* @return int整型
*/
// 常用-集合
function Nqueen( n ) {
// write code here
let column = new Set();// 标记列不可用
let pos = new Set();// 标记正斜线不可用
let neg = new Set();// 标记反斜线不可用
let result = 0;
const compute = (i,n) =>{
if(i === n){
result ++;
return;
}
for(let j =0;j < n;j++){
if(column.has(j) || pos.has(i - j) || neg.has(i+j)){
continue;
}
column.add(j);// 列号j
pos.add(i-j);// 行号i - 列号j 正斜线
neg.add(i+j);// 行号i + 列号j 反斜线
compute(i+1,n);// 计算下一行
// 完成上一步递归计算后,清除
column.delete(j);
pos.delete(i-j);
neg.delete(i+j)
}
}
compute(0,n);
return result;
}
module.exports = {
Nqueen : Nqueen
};
参考Java大神写的
具体做法:
1.设置三个集合分别记录不能再被选中的的列col,正斜线pos,反斜线neg
2.经规律发现 行号i - 列号j 可确定唯一正斜线,行号i + 列号j 可确定唯一反斜线
3.符合要求的点记录当前点并递归下一个皇后,最后一个皇后成功安置后将res+1,然后需回溯回初始点将初始点删除,将初始点的皇后放置其他位置进行判断
4.不符合要求的需要进行循环
1.设置三个集合分别记录不能再被选中的的列col,正斜线pos,反斜线neg
2.经规律发现 行号i - 列号j 可确定唯一正斜线,行号i + 列号j 可确定唯一反斜线
3.符合要求的点记录当前点并递归下一个皇后,最后一个皇后成功安置后将res+1,然后需回溯回初始点将初始点删除,将初始点的皇后放置其他位置进行判断
4.不符合要求的需要进行循环

京公网安备 11010502036488号