一起刷LeetCode——N皇后(回溯)

130 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第22天,点击查看活动详情

N皇后

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。 给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。 每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。

来源:力扣(LeetCode) 链接:leetcode.cn/problems/n-…

分析

  • 超级经典的回溯题目,当有两个以及两个以上的皇后时,要想让皇后彼此之间不相互攻击,那就需要皇后两两之间不能再同一行同一列同一斜线
  • 所以在布置皇后的时候,使用二维数组来记录棋盘状态,从列入手,一列只能放一个皇后,然后再判断要放的那个棋盘格子左边右边以及斜对角是否有皇后,直到确定当前格子是个可以放皇后的格子,一次类推把n个皇后都放到棋盘中

代码

var solveQueens = function(n){
    let chessBoard = new Array(n)
    for(let i=0;i<n;i++){
        chessBoard[i] = new Array(n).fill('.')
    }
    let res = []
    let isValidQueen = function(row, col){
        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--){
            if(chessBoard[i][j] === 'Q') return false
        }
        for(let i=row-1,j=col+1;i>=0 & j<=n-1;i--,j++){
            if(chessBoard[i][j] === 'Q') return false
        }
        return true
    }
    var backtrack = function(row){
        if(row === n){
            res.push([...chessBoard].map(row => row.join('')))
            return
        }
        for(let col = 0;col<n;col++){
            if(isValidQueen(row,col)){
                if(isValidQueen(row, col)) {
                    chessBoard[row][col] = "Q";
                    backtrack(row + 1);
                    chessBoard[row][col] = ".";
                }
            }
        }
    }
    backtrack(0)
    return result;
}

总结

  • N皇后是经典的回溯算法题目,符合不同的状态迁移,以及回溯到某个元素之后是否符合答案要求的判断
  • 今天也是有收获的一天