首页 > 技术文章 > N皇后问题

johnjackson 2019-11-04 09:40 原文

题目:https://leetcode-cn.com/problems/n-queens/
        /**
         * @param {number} n
         * @return {string[][]}
         */
        var solveNQueens = function (n) {
            if (n == 1) return [["Q"]];
            let solutions = [];
            let solution = initArrayData(n);//[['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']];
            let progress = [];
            let put_count = 0;
            let start_col = 0;
            // let start_row = 0;
            // debugger;
            // 按行数遍历(算法中遇到失败的方案,可能回返回前一行重新尝试,所以循环次数可能大于n)
            for (let row = 0; row < n; row++) {
                let is_put = false;  //表示当前行是否放入了Q
                for (let col = start_col; col < n; col++) {
                    if (solution[row][col] == '') {
                        //有空格子,则放一个Q
                        putQueen(row, col);
                        //将当前步骤的方案进度暂存起来,如果后面的步骤失败,则用来返回重试,相当于玩游戏时的存盘和读档
                        progress.push({
                            row: row,
                            col: col,
                            solution: JSON.stringify(solution)
                        });
                        is_put = true;
                        put_count++;
                        break;
                    }
                }
                // 如果当前行没有放入Q,则说明到此步的解决方案不正确,需要返回上一行重试(相当于玩游戏读档)
                if (!is_put) {
                    if (progress.length) {
                        let step = progress.pop();
                        start_col = step.col + 1;
                        row = step.row - 1; //因为循环时每次row自增1,所以为了回到上一行,这里要-1
                        solution = progress.length ? JSON.parse(progress[progress.length - 1].solution) : initArrayData(n);
                        put_count--;
                        continue;
                    } else {
                        //如果当前行一个Q没放,并且没有暂存的进度,则说明此方案失败
                        return solutions;
                    }
                } else {
                    //当前行放了一个Q,则下一行还是从第一列开始处理
                    start_col = 0;
                }
                if (row == n - 1) {
                    if (put_count == n) {
                        let ret = translateSolution(solution);
                        // console.log(ret);
                        solutions.push(ret);

                        let step = progress.pop();
                        start_col = step.col + 1;
                        row = step.row - 1;
                        solution = progress.length ? JSON.parse(progress[progress.length - 1].solution) : initArrayData(n);
                        put_count--;
                        continue;

                    } else {
                        // console.log('到最后一行,但是Q没有放全');
                        return solutions;
                    }
                }
            }

            function putQueen(x, y) {
                for (let i = 0; i < n; i++) {
                    solution[x][i] = '.';
                }
                for (let i = x+1; i < n; i++) {
                    solution[i][y] = '.';
                }
                //向左上方填 .
                // for (let i = x, j = y; i >= 0 && j >= 0; i-- , j--) {
                //     solution[i][j] = '.';
                // }

                ///向右上方填 .
                // for (let i = x, j = y; i >= 0 && j < n; i-- , j++) {
                //     solution[i][j] = '.';
                // }

                // 向右下方填 .
                for (let i = x, j = y; i < n && j < n; i++ , j++) {
                    solution[i][j] = '.';
                }
                //向左下方填 .
                for (let i = x, j = y; i < n && j >= 0; i++ , j--) {
                    solution[i][j] = '.';
                }
                solution[x][y] = 'Q';
            }

            function translateSolution(solution) {
                return solution.map((item) => {
                    return item.join('');
                });
            }
            function initArrayData(n) {
                let solution = [];
                for (let i = 0; i < n; i++) {
                    solution[i] = [];
                    for (let j = 0; j < n; j++) {
                        solution[i][j] = '';
                    }
                }
                return solution;
            }

            return solutions;
        };

 

推荐阅读