N皇后問題
n 皇后問題研究的是如何將 n 個皇后放置在 n×n 的棋盤上,並且使皇后彼此之間不能相互攻擊。
上圖爲 8 皇后問題的一種解法。
給定一個整數 n,返回所有不同的 n 皇后問題的解決方案。
每一種解法包含一個明確的 n 皇后問題的棋子放置方案,該方案中 ‘Q’ 和 ‘.’ 分別代表了皇后和空位。
示例:
輸入: 4
輸出: [
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解釋: 4 皇后問題存在兩個不同的解法。
Java代碼實現:
public class SolveNQueens {
public List<List<String>> solveNQueens(int n) {
int[] state = new int[n];//用來記錄n個皇后位置的數組
List<List<String>> res = new ArrayList<>();//記錄結果
nQueue(res, state, 0, n);
return res;
}
public void nQueue(List<List<String>> res, int[] state, int cur, int n) {
// 遞歸結束的條件:當前行等於n
if (cur == n) {
List<String> temp = new ArrayList<>();//用來保存每一行的皇后的位置
for (int i = 0; i < state.length; i++) {
StringBuilder s = new StringBuilder("");
for (int j = 0; j < state.length; j++) {
if (j != state[i]) {//判斷皇后是否在當前位置
s.append(".");
}else{
s.append("Q");
}
}
temp.add(s.toString());
}
res.add(temp);//用來保存所有行的皇后的位置
return;
}
for (int pos = 0; pos < state.length; pos++) {//遍歷判斷皇后可以放置的列
state[cur] = pos;//假設把皇后當前行的pos列
boolean flag = true;//假設可以放在當前位置
for (int col = 0; col < cur; col++) {//判斷當前位置是否合法
boolean b1 = (pos == state[col]);//判斷是否在同一列
boolean b2 = (Math.abs(cur - col) == Math.abs(pos - state[col]));//判斷是否在對角線
if (b1 || b2) {//兩個條件任意一個爲true
flag = false;//說明在同一列或對角線,皇后被攻擊,將flag置爲false,退出本層循環,返回上一行的下一列繼續進行判斷
break;
}
}
if (flag == true) {//flag爲true,說明當前位置合理,遞歸進入進入下一行
nQueue(res, state, cur + 1, n);
}
}
}
@Test
public void myTest(){
List<List<String>> lists = solveNQueens(4);
System.out.println(lists);
}
}
輸出結果: