N皇后问题--解法一(递归遍历斜线)
import java.util.*;
import java.math.*;
public class Solution {
TreeSet<Integer> ready = new TreeSet<Integer>();
HashSet<Integer> res = new HashSet<Integer>();
Integer midNum = 0;
//已经摆放几个
int leng = 0;
//多少种摆法
int count = 0;
int len = 0;
boolean found = false;
HashSet<Integer> readyX = new HashSet<Integer>();
HashSet<Integer> readyY = new HashSet<Integer>();
/**
*
* @param n int整型 the n
* @return int整型
*/
public int Nqueen (int n) {
len = n;
recursion();
return res.size();
}
private void recursion() {
if (leng == len) {
midNum = 0;
//ready 元素顺序不同,迭代的直不同,所以要去重的话,只能使用treeset排序
ready.forEach(x-> midNum = 31*midNum + x);
//利用hashset去重
res.add(midNum);
// }
return;
}
for (int x = 1 ; x <= len; x++ ) {
for (int y = 1 ; y <= len ; y++) {
found = false;
//沿着斜线判断
find(x, y, 1);
find(x, y, 2);
find(x, y, 3);
find(x, y, 4);
if (!found && !readyX.contains(x) && !readyY.contains(y)) {
leng++;
int hashCode = 31 * (31 * 1 + y) + x;
// String hashCode = x + "-" + y;
ready.add(hashCode);
readyX.add(x);
readyY.add(y);
//进入下一个寻找Q的迭代
recursion();
//每确定一个Q的位置,回溯
//回溯只能保证当前Q进入其他分支,但是其他Q仍然可以在当前分支
//而每个Q的位置要考虑的是组合而不是排列
ready.remove(hashCode);
readyX.remove(x);
readyY.remove(y);
leng--;
//一行只能有一个Q
break;
}
}
}
}
private void find(int x, int y, int num) {
if (found) {
return;
}
int hashCode = 31 * (31 * 1 + y) + x;
//String hashCode = x + "-" + y;
if (ready.contains(hashCode)) {
found = true;
return;
}
//斜线
if (num == 1 && x < len && y < len)
find(x + 1, y + 1, 1);
if (num == 2 && x < len && y > 0)
find(x + 1, y - 1, 2);
if (num == 3 && x > 0 && y < len)
find(x - 1, y + 1, 3);
if (num == 4 && x > 0 && y > 0)
find(x - 1, y - 1, 4);
}
}
n = 9 运行时间 7s
浙公网安备 33010602011771号