51. N-Queens

经典的题目……很有趣

ref:http://blog.csdn.net/hackbuteer1/article/details/6657109

 

首先说一下判断一个格子是不是能放,行列+两侧斜角比较非常笨重,可以用一个一维数组来表示int[] queuePos = new int[n]. 每一个格子表示这行上皇后的位置。

1. 首先一个行只有一个皇后的位置,所以行自然没有重复的皇后

2. 对于列,我们寻找到现在这一行之前的所有行,有没有皇后已经被放在同样的列上,如果没有就可以放

3. 对于斜角,处在斜角上的格子有一个性质Math.abs(row - rowWeWannaPlace) == Math.abs(queuePos[row] - colWeWannaPlace). 所以也是检查一遍就行了

 

helper函数接受两个参数,一个queuePos的一维数组,一个当前行

 1 如果当前行 == n
 2 
 3   添加结果
 4 
 5 不然对于每一列
 6 
 7   如果这个位置能放
 8 
 9     放皇后在这个位置上
10 
11     递归helper(row + 1)

 

所以整体的代码是:

 1     public List<List<String>> solveNQueens(int n) {
 2         List<List<String>> res = new ArrayList<>();
 3         int[] queuePos = new int[n];
 4         Arrays.fill(queuePos, -1);
 5         queue(res, queuePos, 0);
 6         return res;
 7     }
 8     
 9     private boolean canPlace(int[] queuePos, int row, int col) {
10         for(int i = 0; i < row; i++) {
11             if(queuePos[i] == col) {
12                 return false;
13             }
14             if(Math.abs(i - row) == Math.abs(queuePos[i] - col)) {
15                 return false;
16             }
17         }
18         return true;
19     }
20     
21     private void queue(List<List<String>> res, int[] queuePos, int row) {
22         int n = queuePos.length;
23         if(row == n) {
24             List<String> cur = generateResStr(queuePos);
25             res.add(cur);
26             return;
27         }
28         for(int i = 0; i < n; i++) {
29             if(canPlace(queuePos, row, i)) {
30                 queuePos[row] = i;
31                 queue(res, queuePos, row + 1);
32             }
33         }
34     }
35     
36     private List<String> generateResStr(int[] queuePos) {
37         int n = queuePos.length;
38         char[] row = new char[n];
39         Arrays.fill(row, '.');
40         List<String> res = new ArrayList<>();
41         for(int i = 0; i < queuePos.length; i++) {
42             row[queuePos[i]] = 'Q';
43             res.add(new String(row));
44             Arrays.fill(row, '.');
45         }
46         return res;
47     }

相当于遍历一棵树,树的层数是N,每层的节点数数是可以放的列,所以总复杂度是O(n!)

 

posted @ 2016-10-17 03:51  warmland  阅读(195)  评论(0编辑  收藏  举报