n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
示例:
输入: 4
输出: [
[".Q…", // 解法 1
“…Q”,
“Q…”,
“…Q.”],
["…Q.", // 解法 2
“Q…”,
“…Q”,
“.Q…”]
]
解释: 4 皇后问题存在两个不同的解法。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/n-queens
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
目前想到的是这种解法,效率一般。
public static void main(String[] args) {
// printList(solveNQueens(4));
printList(solveNQueens(5));
}
private static List<List<String>> resList=new ArrayList<>();
private static Integer N;
public static List<List<String>> solveNQueens(int n) {
resList=new ArrayList<>();
N=n;
List<Integer> queenIndex=new ArrayList<>();
for (int i = 0; i <N ; i++) {
queenIndex.add(i);
dfs(queenIndex);
queenIndex.remove(queenIndex.size()-1);
}
return resList;
}
//n皇后问题必然是每一行都有皇后。
//用一个queenIndex表示 皇后在每个行出现的位置。
//我们只需要在每一行找皇后能出现的位置,然后进入下一行。
//当进行到queenIndex为N时返回结果。
public static void dfs(List<Integer> queenIndex){
//获取到解
if(queenIndex.size()==N){
addAnswer(queenIndex);
return;
}
List<Integer> retain=getRetain(queenIndex); //当前行可用的位置
if (retain.size()==0) return; //没有可用位置返回
for (int i = 0; i < retain.size(); i++) {
//添加解,进入下一层
queenIndex.add(retain.get(i));
dfs(queenIndex);
queenIndex.remove(queenIndex.size()-1); //回溯
}
}
//将当前解添加到答案中
public static void addAnswer(List<Integer> queenIndex){
List<String> list=new ArrayList<>();
for (int i = 0; i < N; i++) {
StringBuilder builder=new StringBuilder();
for (int j = 0; j < N; j++) {
if(j==queenIndex.get(i)){
builder.append("Q");
}else {
builder.append(".");
// builder.append("O");
}
}
list.add(builder.toString());
}
resList.add(list);
}
//获取下一行可以选的位置数的列表
public static List<Integer> getRetain(List<Integer> queenIndex){
Set<Integer> set=new HashSet<>(); //当前行可用的位置
int row=queenIndex.size(); //获取当前行
for (int i = 0; i < queenIndex.size(); i++) {
set.add(queenIndex.get(i));
set.add(queenIndex.get(i)-row+i);
set.add(queenIndex.get(i)+row-i);
}
List<Integer> retain=new ArrayList<>();
for (int i = 0; i <N ; i++) {
if(!set.contains(i)){
retain.add(i);
}
}
return retain;
}
//写一个打印方法检查数据
public static void printList(List<List<String>> lists){
for (int i = 0; i < lists.size(); i++) {
List<String> list=lists.get(i);
for (int j = 0; j < list.size(); j++) {
System.out.println(list.get(j));
}
System.out.println("======================");
}
}