51. N 皇后

题目描述

按照国际象棋的规则,

皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。

n 皇后问题 研究的是

  • 如何将 n 个皇后放置在 n*n 的棋盘上
  • 并且使皇后彼此之间不能相互攻击

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

每一种解法包含一个不同的 n 皇后问题 的棋子放置方案

该方案中 'Q''.' 分别代表了皇后和空位。

示例1

leet code 51. N 皇后_结果集

示例2

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

提示

1 <= n <= 9

题目解析

  • 明确题目要求
  • 给定的参数有 n : 表示 n 个皇后,需要放置在 n*n 的棋盘上
  • 并且保证 皇后 之间彼此不能互相攻击
  • 皇后攻击规则:同一行或同一列或同一斜线上的棋子

  • 很显然,需要穷举每一种可能
  • 然后统计保存符合题目要求的结果

  1. 尝试把第一个皇后放置在第一个位置,坐标[0, 0]----
  2. 这里理解错误,因为行互斥,所以应该是尝试第一行放置皇后
  1. 然后标记一下被放置的位置,以及可能被攻击的位置
  1. 然后尝试在下一行 放置 下一个皇后
  2. 直到所有的皇后被放置完
  3. 把符合条件的方案添加到结果集中

show code

class Solution {
    // 创建结果集
    private List<List<String>> ans;


    public List<List<String>> solveNQueens(int n) {
        // 初始化结果集
        ans = new ArrayList<>();
        // 创建一个二维矩阵,来标识保存皇后被放置的位置
        char[][] chessboard = new char[n][n];
        // 初始化棋盘的值
        for (char[] chars : chessboard) {
            Arrays.fill(chars, '.');
        }
        // 进入回溯,棋盘  和  当前的行
        bt(chessboard, 0);
        return ans;
    }

    private void bt(char[][] chessboard, int row) {
        // 如果放置的皇后数等于 n
        if (row == chessboard.length) {
            toAnswer(chessboard);
            return;
        }

        // 遍历当前行
        for (int j = 0; j < chessboard.length; j++) {
            if (chessboard[row][j] == '.' && check(row, j, chessboard)) {
                // 放置皇后.
                chessboard[row][j] = 'Q';

                // 回溯
                bt(chessboard, row + 1);

                // 取消放置的皇后
                chessboard[row][j] = '.';
            }
        }
    }

    private boolean check(int i, int j, char[][] chessboard) {
        // 判断 i j 位置是否满足放置一个皇后的条件
        int n = chessboard.length;
        // 判断列
        for (int k = 0; k < n; k++) {
            if (chessboard[k][j] == 'Q') {
                return false;
            }
        }
        // i--,j++ 右上方
        for (int i1 = i - 1, j1 = j + 1; i1 >= 0 && j1 < n; i1--, j1++) {
            if (chessboard[i1][j1] == 'Q') {
                return false;
            }
        }
        // i--,j-- 左上方
        for (int i1 = i - 1, j1 = j - 1; i1 >= 0 && j1 >= 0; i1--, j1--) {
            if (chessboard[i1][j1] == 'Q') {
                return false;
            }
        }
        return true;
    }

    private void toAnswer(char[][] chessboard) {
        List<String> ret = new ArrayList<>();

        for (char[] chars : chessboard) {
            StringBuilder builder = new StringBuilder();
            for (char aChar : chars) {
                builder.append(aChar);
            }
            ret.add(builder.toString());
        }
        ans.add(ret);
    }
}