Leetcode - 51. N 皇后

解题思路参考代码中的注释:
class Solution {

    // cols[i]表示第i列是否存在皇后
    private boolean[] cols;

    // forwardSlashs[i]表示第i根从右上到左下的斜线上是否存在皇后,最左上角那个位置是第0根这样的斜线
    private boolean[] forwardSlashs;

    // backSlashs[i]表示第i根从左上到右下的斜线上是否存在皇后,最左下角那个位置是第0根这样的斜线
    private boolean[] backSlashs;

    // puzzle表示棋盘
    private char[][] puzzle;

    // n表示棋盘的维度
    private int n;

    // 计算某个位置在哪根斜线上
    private int getSlashIndex(int x, int y, boolean isForward) {
        
        // 如果是计算右上到左下的斜线的下标:
        //     (0, 0)位于第0根斜线,(1, 0)和(0, 1)位于第1根斜线,因此斜线下标为x + y
        // 如果是计算左上到右下的斜线的下标:
        //     (n - 1, 0)位于第0根斜线,(n - 2, 0)和(n - 1, 1)位于第1根斜线,因此斜线下标为n - 1 - x + y
        return isForward ? (x + y) : (n - 1 - x + y);
    }

    // 使用回溯法
    public List<List<String>> solveNQueens(int n) {
        List<List<String>> ret = new ArrayList<>();
        
        // 初始化成员变量
        this.n = n;
        this.cols = new boolean[n];
        this.forwardSlashs = new boolean[n + n - 1];
        this.backSlashs = new boolean[n + n - 1];
        this.puzzle = new char[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                this.puzzle[i][j] = '.';
            }
        }
        
        // 从第0行开始放置皇后
        putAQueenInThisRow(0, ret);
        return ret;
    }

    private void putAQueenInThisRow(int r, List<List<String>> ret) {
        
        // r == n说明棋盘已经放置完成,因此将此时的棋盘状态保存到ret中
        if (r == n){
            List<String> list = new ArrayList<>();
            for (char[] row : puzzle) {
                list.add(new String(row));
            }
            ret.add(list);
            return;
        }

        // 如果还没有放置完成,则开始在本行的第1到n列逐个尝试放置皇后
        for (int i = 0; i < n; i++){

            int forwardSlashIndex = getSlashIndex(r, i, true);
            int backSlashIndex = getSlashIndex(r, i, false);
            
            // 如果当前列或当前斜线上已经有皇后了,则跳过
            if (cols[i] || forwardSlashs[forwardSlashIndex] || backSlashs[backSlashIndex]) {
                continue;
            }
            
            // 否则在本行的第i列上放置皇后
            cols[i] = forwardSlashs[forwardSlashIndex] = backSlashs[backSlashIndex] = true;
            puzzle[r][i] = 'Q';

            // 然后再在第r + 1行放置皇后
            putAQueenInThisRow(r + 1, ret);

            // 回溯
            cols[i] = forwardSlashs[forwardSlashIndex] = backSlashs[backSlashIndex] = false;
            puzzle[r][i] = '.';
        }
    }
}
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务