N皇后问题
n 皇后问题:
如何将 n 个皇后放置在 n×n 的棋盘上,
并且使皇后彼此之间不能相互攻击(不在同一行,同一列,同一对角线上)。
给定一个整数 n ,返回有多少种摆放方法。
两种解法
public class N皇后 {
public static int way1(int n) {
if (n < 0) {
return -1;
}
int[] record = new int[n];
return wayFun1(0, n, record);
}
private static int wayFun1(int cur, int n, int[] record) {
if (cur == n) {
return 1;
}
int res = 0;
for (int i = 0; i < n; i++) {
if (isValid(record, cur, i)) {
record[cur] = i;
res += wayFun1(cur + 1, n, record);
}
}
return res;
}
private static boolean isValid(int[] record, int i, int j) {
for (int k = 0; k < i; k++) {
if (record[k] == j || Math.abs(i - k) == Math.abs(j - record[k])) {
return false;
}
}
return true;
}
public static int way2(int n) {
if (n < 0 || n > 32) {
return -1;
}
int limit = n == 32 ? -1 : (1 << n) - 1;
return wayFun2(limit, 0, 0, 0);
}
public static int wayFun2(int limit, int colLimit, int leftLimit, int rightLimit) {
if (colLimit == limit) {
return 1;
}
int res = 0;
int t = limit & ~(colLimit | leftLimit | rightLimit);
while (t != 0) {
int p = t & (~t + 1);
res += wayFun2(limit,
colLimit | p,
(leftLimit | p) << 1,
(rightLimit | p) >>> 1);
t -= p;
}
return res;
}
public static void main(String[] args) {
for (int i = 0; i <= 12; i++) {
System.out.printf("当前为%d皇后问题,暴力递归法答案:%d,位运算改进法答案:%d\n", i, way1(i), way2(i));
}
}
}
问题答案
当前为0皇后问题,暴力递归法答案:1,位运算改进法答案:1
当前为1皇后问题,暴力递归法答案:1,位运算改进法答案:1
当前为2皇后问题,暴力递归法答案:0,位运算改进法答案:0
当前为3皇后问题,暴力递归法答案:0,位运算改进法答案:0
当前为4皇后问题,暴力递归法答案:2,位运算改进法答案:2
当前为5皇后问题,暴力递归法答案:10,位运算改进法答案:10
当前为6皇后问题,暴力递归法答案:4,位运算改进法答案:4
当前为7皇后问题,暴力递归法答案:40,位运算改进法答案:40
当前为8皇后问题,暴力递归法答案:92,位运算改进法答案:92
当前为9皇后问题,暴力递归法答案:352,位运算改进法答案:352
当前为10皇后问题,暴力递归法答案:724,位运算改进法答案:724
当前为11皇后问题,暴力递归法答案:2680,位运算改进法答案:2680
当前为12皇后问题,暴力递归法答案:14200,位运算改进法答案:14200