八皇后含义:
在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问一共有多少种摆法。
递归回溯的方法。
当我们选择了第一个皇后的位置之后,与其处于同行同列同斜线的位置便都无法被选择,第二个皇后只能放在未被第一个皇后所辐射到的位置上,接着放置第三个皇后,同样不能放在被前两个皇后辐射到的位置上,若此时已经没有未被辐射的位置能够被选择,也就意味着这种摆法是不可行的,我们需要回退到上一步,给第二个皇后重新选择一个未被第一个皇后辐射的位置,再来看是否有第三个皇后可以摆放的位置,如还是没有则再次回退至选择第二个皇后的位置,若第二个皇后也没有更多的选择则回退到第一个皇后,重新进行位置的选择。
代码
function eigther(num){
const result = []
const arr = []
// 先定义一个 8 x 8 的二维数组,里面全都是0
for(let i = 0; i < num; i++){
arr[i] = []
for(let j = 0; j < num; j++){
arr[i].push(0)
}
}
let count = 0;
const loop = (arr, row) => {
// 行数都执行完了,则计数
if(row === num) {
count++
return
}
// 循环的是列
for(let col = 0; col < num; col++){
// 如果该行该列的同一列,或者左上角或右上角,都没有皇后了,则放置一个
if(isSafe(arr, row, col)){
arr[row][col] = 1;
// 继续找下一行
loop(arr, row+1)
// 这一行的这一列使用完毕后,退出来,该进行下一列
arr[row][col] = 0;
}
}
}
loop(arr, 0)
// 判断每一列 和 左右对角是否有皇后
function isSafe(arr,row,col){
// 同一列是否值为1
for(let i = 0; i < num; i++){
if(arr[i][col] === 1) return false
}
// 左上角
for(let i = row - 1, j = col - 1; i >= 0 && j >= 0; i--,j--){
if(arr[i][j] === 1) return false
}
// 右上角
for(let i = row - 1, j = col + 1; i >= 0 && j < num; i--,j++){
if(arr[i][j] === 1) return false
}
return true
}
console.log('count', count);
return result
}
console.time('h');
const r = eigther(8)
console.log(r);
console.log(r.length);
console.timeEnd('h');
参考:https://segmentfault.com/a/1190000022796572
第二种只用一维数组,可以再深入看看。