八皇后含义:
在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问一共有多少种摆法。
递归回溯的方法。
当我们选择了第一个皇后的位置之后,与其处于同行同列同斜线的位置便都无法被选择,第二个皇后只能放在未被第一个皇后所辐射到的位置上,接着放置第三个皇后,同样不能放在被前两个皇后辐射到的位置上,若此时已经没有未被辐射的位置能够被选择,也就意味着这种摆法是不可行的,我们需要回退到上一步,给第二个皇后重新选择一个未被第一个皇后辐射的位置,再来看是否有第三个皇后可以摆放的位置,如还是没有则再次回退至选择第二个皇后的位置,若第二个皇后也没有更多的选择则回退到第一个皇后,重新进行位置的选择。
代码
function eigther(num){const result = []const arr = []// 先定义一个 8 x 8 的二维数组,里面全都是0for(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){// 同一列是否值为1for(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
第二种只用一维数组,可以再深入看看。
