程序媛詹妮弗
终身学习

The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.

Given an integer n, return all distinct solutions to the n-queens puzzle.

Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space respectively.

Example:

Input: 4
Output: [
 [".Q..",  // Solution 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // Solution 2
  "Q...",
  "...Q",
  ".Q.."]
]
Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above.

题目

NxN棋盘摆N个棋子,要求不能同行、同列、同对角线、同反对角线,返回所有摆法。

 

思路

DFS: C[i] 表示第i行皇后所在的列编号,即在位置 (i, C[i])上放了一个皇后,这样用一个一维数组,就能记录整个棋盘。

 

代码

 1 /* 
 2 TIME: O(n!*n)    n行*每行从n 到 n-1 到 n-2...1  即 n!
 3 SPACE: O(n)
 4 */
 5 
 6 class Solution {
 7       public List<List<String>> solveNQueens(int n) {
 8         List<List<String>> result = new ArrayList<>();
 9         int[] C = new int[n]; // C[i]表示第i行皇后所在的列编号,从二维降到一维
10         dfs(C, 0, result);
11         return result;
12     }
13     private static void dfs(int[] C, int row, List<List<String>> result) {
14         int N = C.length;
15         if (row == N) { // 终止条件,也是收敛条件,意味着找到了一个可行解
16             List<String> solution = new ArrayList<>();
17             // 第i行
18             for (int i = 0; i < N; ++i) {
19                 char[] charArray = new char[N];
20                 Arrays.fill(charArray, '.');
21                 //第j列
22                 for (int j = 0; j < N; ++j) {
23                     if (j == C[i]) charArray[j] = 'Q';
24                 }
25                 solution.add(new String(charArray));
26             }
27             result.add(solution);
28             return;
29         }
30 
31         for (int j = 0; j < N; ++j) {  // 扩展状态,一列一列的试
32             boolean ok = isValid(C, row, j);
33             if (!ok) continue;  // 剪枝,如果非法,继续尝试下一列
34             // 执行扩展动作
35             C[row] = j;
36             dfs(C, row + 1, result);
37             // 撤销动作
38             // C[row] = -1;
39         }
40     }
41 
42     /**
43      * 能否在 (row, col) 位置放一个皇后.
44      *
45      * @param C 棋局
46      * @param row 当前正在处理的行,前面的行都已经放了皇后了
47      * @param col 当前列
48      * @return 能否放一个皇后
49      */
50     private static boolean isValid(int[] C, int row, int col) {
51         for (int i = 0; i < row; ++i) {
52             // 在同一列
53             if (C[i] == col) return false;
54             // 在同一对角线上
55             if (Math.abs(i - row) == Math.abs(C[i] - col)) return false;
56         }
57         return true;
58     }
59 }

 

posted on 2018-10-21 03:23  程序媛詹妮弗  阅读(141)  评论(0编辑  收藏  举报