Ref: https://pdai.tech/md/algorithm/alg-core-backtracking.html#n-%E7%9A%87%E5%90%8E
    image.png
    在 n*n 的矩阵中摆放 n 个皇后,并且每个皇后不能在同一行,同一列,同一对角线上,求所有的 n 皇后的解。
    一行一行地摆放,在确定一行中的那个皇后应该摆在哪一列时,需要用三个标记数组来确定某一列是否合法,这三个标记数组分别为:列标记数组、45 度对角线标记数组和 135 度对角线标记数组。

    45 度对角线标记数组的维度为 2 n - 1,通过下图可以明确 (r, c) 的位置所在的数组下标为 r + c:
    image.png
    135 度对角线标记数组的维度也是 2
    n - 1,(r, c) 的位置所在的数组下标为 n - 1 - (r - c):
    image.png

    1. private List<List<String>> solutions;
    2. private char[][] nQueens;
    3. private boolean[] colUsed;
    4. private boolean[] diagonals45Used;
    5. private boolean[] diagonals135Used;
    6. private int n;
    7. public List<List<String>> solveNQueens(int n) {
    8. solutions = new ArrayList<>();
    9. nQueens = new char[n][n];
    10. for (int i = 0; i < n; i++) {
    11. Arrays.fill(nQueens[i], '.');
    12. }
    13. colUsed = new boolean[n];
    14. diagonals45Used = new boolean[2 * n - 1];
    15. diagonals135Used = new boolean[2 * n - 1];
    16. this.n = n;
    17. backtracking(0);
    18. return solutions;
    19. }
    20. private void backtracking(int row) {
    21. if (row == n) {
    22. List<String> list = new ArrayList<>();
    23. for (char[] chars : nQueens) {
    24. list.add(new String(chars));
    25. }
    26. solutions.add(list);
    27. return;
    28. }
    29. for (int col = 0; col < n; col++) {
    30. int diagonals45Idx = row + col;
    31. int diagonals135Idx = n - 1 - (row - col);
    32. if (colUsed[col] || diagonals45Used[diagonals45Idx] || diagonals135Used[diagonals135Idx]) {
    33. continue;
    34. }
    35. nQueens[row][col] = 'Q';
    36. colUsed[col] = diagonals45Used[diagonals45Idx] = diagonals135Used[diagonals135Idx] = true;
    37. backtracking(row + 1);
    38. colUsed[col] = diagonals45Used[diagonals45Idx] = diagonals135Used[diagonals135Idx] = false;
    39. nQueens[row][col] = '.';
    40. }
    41. }