javascript递归回溯解决N皇后问题

614 阅读1分钟

什么是N皇后问题?

juejin.cn/post/684490…

代码实现

结果不考虑矩阵翻转重复的问题

class RecursionTracing {
    constructor(n) {
        this.n = n
        this.initArr(n)
        this.settle(0)
    }

    n = 0  // 皇后数量
    arr = [] // 当前棋盘排列
    result = [] // 所有的结果集

    // 初始化棋盘为一个二位数组,且都为0
    initArr =function(n) {
        let arr = []
        for(let i = 0;i < this.n; i++) {
            arr[i] = []
            for(let j = 0;j < this.n;j++) {
                arr[i][j] = 0
            }
        }
        this.arr = arr
    }

    // 检查当前插入的坐标是否符合规则
    check = function(x, y) {
        for(let i = 0; i < x; i++) {
    
            // 不能同一行
            if(this.arr[i][y] === 1) {
                return false
            }
    
            // 左斜上方不能有皇后
            if(y + x - i < this.n && this.arr[i][y + x - i] === 1) {
                return false
            }
    
            // 左斜下方不能有皇后
            if(y + i - x >= 0 && this.arr[i][y + i - x] === 1) {
                return false
            }
        }
        return true
    }

    // 递归回溯(核心)
    settle = function(x) {
        if(x === this.n) {
            return this.result.push(JSON.parse(JSON.stringify(this.arr)))
        }

        for(let i = 0; i < this.n; i++) {

            // 避免数据污染
            for(let j = 0; j < i; j++) {
                this.arr[x][j] && (this.arr[x][j] = 0)
            }

            if(this.check(x, i)) {
                this.arr[x][i] = 1
                this.settle(x + 1)
                this.arr[x][i] = 0
            }
        }  
    }

    // 打印结果
    print = function() {
        console.log(this.result)
    }
}

// 以8皇后为例
let recursionTracing =  new RecursionTracing(10)
recursionTracing.print()