代码随想录算法训练营第三十天 | N 皇后

51. N 皇后

leetcode
文档题解
视频题解

根据 n 创建一个二维数组,填充满 '.'。在每一行选中一个位置放入皇后,如果合法的话,就继续递归探测下一行,因为不能再放在当前行,放在当前行冲突。

注意 for 循环遍历的是列,递归遍历的是行。

支持的回溯问题操作的都是以为数组,这里开始操作二维数组,理解决策树的宽和高是什么很重要。

class Solution {
    List<List<String>> res = new LinkedList<>();
    public List<List<String>> solveNQueens(int n) {
        char[][] board = new char[n][n];
        // 填充二维数组
        for (char[] b: board) {
            Arrays.fill(b, '.');
        }
        backtrace(board, 0);
        return res;
    }
    public void backtrace(char[][] board, int row) {
        int n = board.length;
        // 放完 n 个皇后,收集答案
        if (row == n) {
            res.add(mapToList(board));
            return;
        }

        for (int col = 0; col < board.length; col++) {
            // 检查皇后放在 [row, col] 是否合法
            if (isValid(board, row, col)) {
                // 合法,再将 Q 放入
                board[row][col] = 'Q';
                // row + 1,递归处理下一行
                backtrace(board, row + 1);
                // 回溯
                board[row][col] = '.';
            }
        }
    }
    // 检查 [row, col] 位置放置皇后的话是否合法
    public boolean isValid(char[][] board, int row, int col) {
        int n = board.length;
        // 不用检查行,因为我们知道不能放在同一行,根本不会往行上放皇后,代码都是递归写的,直接考虑往下一行放皇后
        // 检查列(列不动,遍历行)
        for (int i = 0; i < row; i++) {
            if (board[i][col] == 'Q') return false;
        }
        // 检查 45 度角(只关注前面的元素)
        for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
            if (board[i][j] == 'Q') return false;
        }
        // 检查 135 度角(只关注前面的元素)
        for (int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
            if (board[i][j] == 'Q') return false;
        }
        return true;
    }
    public List<String> mapToList(char[][] board) {
        List<String> list = new LinkedList<>();
        for (char[] b: board) {
            StringBuilder sb = new StringBuilder();
            for (char c : b) {
                sb.append(c);
            }
            list.add(sb.toString());
        }
        return list;
    }
}