/**
Follow up for N-Queens problem.
Now, instead outputting board configurations, return the total number of distinct solutions.
题目大意:N皇后问题,输入N,输出解的个数
经典题目了,皇后们横、竖、斜都不可以碰到
**/
public class Solution {
public int totalNQueens(int n) {
//return solve1(n); //耍流氓
return solve2(n);
}
//========================== solve1 ================================
//“我是流氓我怕谁”大法!!
//跑n=16的时候我的可怜的小手提要跑好久,所以就到这里吧。
//居然Accept了...
private int solve1(int n){
int[] result = {
1, 1, 0, 0, 2,
10, 4, 40, 92, 352,
724, 2680, 14200, 73712, 365596,
2279184
};
return result[n];
}
//========================== solve2 ================================
//来个严肃认真的,这段解释是抄网上的,也不知道出处是哪里啦,写的不错就懒得自己写了
//O(n^3) = O(n) * O(n) * O(n)
//由于要遍历所有可能性,所以复杂度颇高:遍历行 * 遍历列 * 检查
//其实就是个深度优先遍历
/*
回溯法解N皇后问题
使用一个一维数组表示皇后的位置
其中数组的下标表示皇后所在的行
数组元素的值表示皇后所在的列
这样设计的棋盘,所有皇后必定不在同一行
假设前n-1行的皇后已经按照规则排列好
那么可以使用回溯法逐个试出第n行皇后的合法位置
所有皇后的初始位置都是第0列
那么逐个尝试就是从0试到N-1
如果达到N,仍未找到合法位置
那么就置当前行的皇后的位置为初始位置0
然后回退一行,且该行的皇后的位置加1,继续尝试
如果目前处于第0行,还要再回退,说明此问题已再无解
如果当前行的皇后的位置还是在0到N-1的合法范围内
那么首先要判断该行的皇后是否与前几行的皇后互相冲突
如果冲突,该行的皇后的位置加1,继续尝试
如果不冲突,判断下一行的皇后
如果已经是最后一行,说明已经找到一个解,输出这个解
然后最后一行的皇后的位置加1,继续尝试下一个解
*/
private int[] place = null;
private int result = -1;
private int solve2(int n){
//n长度的数组,存储着每一行的皇后的位置
place = new int[n];
//结果的个数
result = 0;
//递归求解
loop(n, 0);
return result;
}
private void loop(int n, int depth){
//如果已经放下最后一个皇后,则解决方案多一个
if(depth == n){
result++;
return;
}
//在当前行进行遍历,选择不同的列
for(int i=0; i<n; i++){
//如果当前列允许放下皇后,那就放下并且递归检查下一个行
if(checkOK(depth, i)){
place[depth] = i;
loop(n, depth+1);
}
}
}
//检查在当前的depth行的第i列是否可放皇后
private boolean checkOK(int depth, int col){
for(int i=0; i<depth; i++)
if(place[i]==col //同一列
|| place[i]+(depth-i) == col //右斜线
|| place[i]-(depth-i) == col) //左斜线
return false;
return true;
}
}
LeetCode:N-Queens II
最新推荐文章于 2019-04-09 23:32:41 发布