N皇后

递归回溯法

function putNQueen(n) {
    let res = []; //最终存放结果的数组
    // 核心依赖俩参数 rowIndex,当前想尝试在第几行上放皇后
    // prev 上一次存放皇后的结果,初始值为 [],放的是对应的列值

    // 三个数组,已放过的列的值、左斜 rowIndex + columnIndex、右斜对角线线的是否放过 rowIndex - columnIndex
    let hasPutColumnArr = [];
    let leftCorner = [];
    let rightCorner = [];

    const record = (rowIndex, columnIndex, bool) => {
        hasPutColumnArr[columnIndex] = bool;
        leftCorner[rowIndex - columnIndex] = bool;
        rightCorner[rowIndex + columnIndex] = bool;
    };
    // 尝试在第n行中摆放皇后的位置
    const putQueen = (rowIndex, prev) => {
        console.log(rowIndex, prev);
        if (rowIndex === n) {
            return res.push(prev);
        }
        for (let columnIndex = 0; columnIndex < n; columnIndex++) {
            const freeColumn = !hasPutColumnArr[columnIndex];
            const freeLeftCorner = !leftCorner[rowIndex + columnIndex];
            const freeRightCorner = !leftCorner[rowIndex - columnIndex];
            // 可放置,则继续递归
            if (freeColumn && freeLeftCorner && freeRightCorner) {
                // 记录当前行列为已放皇后
                record(rowIndex, columnIndex, true);
                // 注意这里prev.concat不会影响出栈后prev的值,prev.concat返回的是拼接后新的值
                // 注意这里如果用是prev.push,第一传进去的push的item,第二会影响后续prev的值
                putQueen(rowIndex + 1, prev.concat(columnIndex));
                // 出栈后将皇后置为未放状态
                record(rowIndex, columnIndex, false);
            }
        }
    };
    putQueen(0, []);
    return res;
}
posted @ 2020-09-08 20:53  萝卜爱吃青菜  阅读(190)  评论(0编辑  收藏  举报