标签:
Description:
Follow up for N-Queens problem.
Now, instead outputting board configurations, return the total number of distinct solutions.
n皇后问题:每两个皇后之间不能在同一行同一列和同一条斜线上。求出问题解的个数。
为了把二维的问题降为一维,可以用一个一维数组来存储,x[i] = j,i表示行,j表示列。对于任意两个皇后来说,必须满足问题的约束条件,有如下结论:
|x[i] - x[k]| != |i - k| && x[k] != x[i]满足这个结论才能放置。
这个问题有个经典的回溯解法。
这个算法将在棋盘上一列一列地摆放皇后直到八个皇后在不相互攻击的情况下都被摆放在棋盘上,算法便终止。当一个新 加入的皇后因为与已经存在的皇后之间相互攻击而不能被摆在棋盘上时,算法便发生回溯。一旦发生这种情况,就试图把最后放在棋盘上的皇后移动到其他地方。这 样做是为了让新加入的皇后能够在不与其它皇后相互攻击的情况下被摆放在棋盘的适当位置上。尽管第7个皇后不会与已经放在棋盘上 的任何一皇后放生攻击,但仍然需要将它移除并发生回溯,因为无法为第8个皇后在棋盘上找到合适的位置。
回溯法因为在发现不合理解后会及时的回溯,所以在整体性能上回比穷举法高很多。
代码:
public class Solution { public int[] x; //当前解 public int sum; //解的个数 public int n; //皇后个数 public int totalNQueens(int n) { this.x = new int[n + 1]; for(int i=0; i<=n; i++) { this.x[i] = 0; } this.sum = 0; this.n = n; backTrack(1); return sum; } public void backTrack(int t) { if(t > n) { sum ++; } else { for(int i=1; i<=n; i++) { this.x[t] = i; if(place(t)) { backTrack(t + 1); //回溯 } } } } /** * 判断当前位置是否合法 */ public boolean place(int k) { for(int j=1; j<k; j++) { if(Math.abs(j-k) == Math.abs(this.x[j]-this.x[k]) || this.x[j] == this.x[k]) { return false; } } return true; } }
标签:
原文地址:http://www.cnblogs.com/wxisme/p/4845224.html