题目

类型:回溯

难度:

N 皇后 - 图1

解题思路

回溯算法解题套路框架

  1. result = []
  2. def backtrack(路径,选择列表):
  3. if 满足结束条件:
  4. result.add(路径)
  5. return
  6. for 选择 in 选择列表:
  7. 做选择
  8. backtrack(路径,选择列表)
  9. 撤销选择

回溯算法

代码

  1. class Solution {
  2. List<List<String>> res = new ArrayList<>();
  3. public List<List<String>> solveNQueens(int n) {
  4. // 记录「路径」
  5. char[][] board = new char[n][n];
  6. for (int i = 0; i < n; i++) {
  7. Arrays.fill(board[i], '.');
  8. }
  9. backtrack(res, board, n, 0);
  10. return res;
  11. }
  12. /**
  13. * 路径:记录在 board 中
  14. * 选择列表: 第 row 行的所有列都是放置皇后的选择
  15. * 结束条件:row 超过 board 的最后一行
  16. *
  17. * @param res
  18. * @param board
  19. * @param n
  20. * @param row
  21. */
  22. public void backtrack(List<List<String>> res, char[][] board, int n, int row) {
  23. // 已经放置了n个皇后-触发结束条件
  24. if (row == n) {
  25. List<String> list = new ArrayList<>();
  26. for (int i = 0; i < n; i++) {
  27. list.add(String.valueOf(board[i]));
  28. }
  29. res.add(list);
  30. return;
  31. }
  32. for (int col = 0; col < n; col++) {
  33. // 判断当前位置是否可以放置皇后-排除不合法的选择
  34. if (!isValid(board, row, col, n)) {
  35. continue;
  36. }
  37. // 做选择-放棋子
  38. board[row][col] = 'Q';
  39. // 进入下一层决策树
  40. backtrack(res, board, n, row + 1);
  41. // 取消选择
  42. board[row][col] = '.';
  43. }
  44. }
  45. /**
  46. * 判断当前位置是否可以放置皇后
  47. *
  48. * @param board
  49. * @param row
  50. * @param col
  51. * @param n
  52. * @return
  53. */
  54. public boolean isValid(char[][] board, int row, int col, int n) {
  55. // 行不需要判断,每行只能有一个皇后
  56. // 判断列
  57. for (int cur = 0; cur < row; cur++) {
  58. if (board[cur][col] == 'Q') return false;
  59. }
  60. // 对角线判断
  61. for (int cur = 1; cur < n; cur++) {
  62. // 主对角线
  63. if (row - cur >= 0 && col - cur >= 0 && board[row - cur][col - cur] == 'Q') {
  64. return false;
  65. }
  66. // 副对角线
  67. if (row - cur >= 0 && col + cur < n && board[row - cur][col + cur] == 'Q') {
  68. return false;
  69. }
  70. }
  71. return true;
  72. }
  73. }