51. N 皇后

https://www.programmercarl.com/0051.N%E7%9A%87%E5%90%8E.html#%E5%85%B6%E4%BB%96%E8%AF%AD%E8%A8%80%E8%A1%A5%E5%85%85
image.png

  1. class Solution {
  2. List<List<String>> result = new ArrayList<>();
  3. private void backTracking(int n, int row, char[][] chessboard) {
  4. //终止条件
  5. if (row == n) {
  6. result.add(Array2List(chessboard));
  7. }
  8. //单层搜索的逻辑:
  9. //递归深度就是row控制棋盘的行,每一层里for循环的col控制棋盘的列,一行一列,确定了放置皇后的位置。
  10. for (int col = 0; col < n; col++) {
  11. if (isValid(row, col, chessboard, n)) { // 验证合法就可以放
  12. chessboard[row][col] = 'Q';//放置皇后
  13. backTracking(n, row + 1, chessboard);//递归
  14. chessboard[row][col] = '.';//回溯 将棋盘重置为.
  15. }
  16. }
  17. }
  18. public List<List<String>> solveNQueens(int n) {
  19. //初始化棋盘,全部为...
  20. char[][] chessboard = new char[n][n];
  21. for (char[] c : chessboard) {
  22. //'.' 表示空,'Q' 表示皇后,初始化空棋盘。
  23. Arrays.fill(c, '.');
  24. }
  25. backTracking(n,0,chessboard);
  26. return result;
  27. }
  28. public List Array2List(char[][] chessboard) {
  29. List<String> list = new ArrayList<>();
  30. for (char[] c : chessboard) {
  31. list.add(String.copyValueOf(c));
  32. }
  33. return list;
  34. }
  35. /**
  36. * 校验
  37. * 不能同行
  38. * 不能同列
  39. * 不能同斜线 (45度和135度角)
  40. *
  41. * @param row
  42. * @param col
  43. * @param chessboard
  44. * @param n
  45. * @return
  46. */
  47. private boolean isValid(int row, int col, char[][] chessboard, int n) {
  48. //检验列
  49. for (int i = 0; i < row; i++) {
  50. if (chessboard[i][col] == 'Q') {
  51. return false;
  52. }
  53. }
  54. //检查45°是否有皇后
  55. for (int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
  56. if (chessboard[i][j] == 'Q') {
  57. return false;
  58. }
  59. }
  60. //检查135°
  61. for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
  62. if (chessboard[i][j] == 'Q') {
  63. return false;
  64. }
  65. }
  66. return true;
  67. }
  68. }