「前端刷题」51. N 皇后

183 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

题目

n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

给你一个整数 n ,返回所有不同的 n皇后问题 的解决方案。

每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q''.' 分别代表了皇后和空位。

 

示例 1:

输入: n = 4 输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]] 解释: 如上图所示,4 皇后问题存在两个不同的解法。

示例 2:

输入: n = 1 输出:[["Q"]]

 

提示:

  • 1 <= n <= 9
  • 皇后彼此不能相互攻击,也就是说:任何两个皇后都不能处于同一条横行、纵行或斜线上。

思路

回溯法 image.png

代码

/**
 * @param {number} n
 * @return {string[][]}
 */
var solveNQueens = function(n) {
    function isValid(row, col, chessBoard, n) {
        //不用判断同一行的因为回溯就是在同一行不同列放置皇后
        for(let i = 0; i < row; i++) {
            // 同一列的判断
            if(chessBoard[i][col] === 'Q') {
                return false
            }
        }
        for(let i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
            // 135度斜角判断 左上斜线 不需要判断下面的
            if(chessBoard[i][j] === 'Q') {
                return false
            }
        }
            // 45度斜角判断 右上斜线 不需要判断下面的
        for(let i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
            if(chessBoard[i][j] === 'Q') {
                return false
            }
        }
        return true
    }

    function transformChessBoard(chessBoard) {
        // 转换一下输出
        let chessBoardBack = []
        chessBoard.forEach(row => {
            let rowStr = ''
            row.forEach(value => {
                rowStr += value
            })
            chessBoardBack.push(rowStr)
        })

        return chessBoardBack
    }

    let result = []
    function backtracing(row,chessBoard) {
        if(row === n) {
            // 最后一行 能放下了就已经算成功了
            result.push(transformChessBoard(chessBoard))
            return
        }
        for(let col = 0; col < n; col++) {
            // 遍历列 回溯行
            if(isValid(row, col, chessBoard, n)) {
                chessBoard[row][col] = 'Q'
                backtracing(row + 1,chessBoard)
                chessBoard[row][col] = '.'
            }
        }
    }
    let chessBoard = Array.from(new Array(n), ()=> new Array(n).fill('.'))
    backtracing(0,chessBoard)
    return result
};

最后

曾梦想仗剑走天涯

看一看世界的繁华

年少的心总有些轻狂

终究不过是个普通人

无怨无悔我走我路