題目鏈接:https://leetcode-cn.com/problems/n-queens/
n 皇后問題研究的是如何將 n 個皇后放置在 n×n 的棋盤上,並且使皇后彼此之間不能相互攻擊。
給定一個整數 n,返回所有不同的 n 皇后問題的解決方案。
每一種解法包含一個明確的 n 皇后問題的棋子放置方案,該方案中
'Q'
和'.'
分別代表了皇后和空位。示例:
輸入: 4 輸出: [ [".Q..", // 解法 1 "...Q", "Q...", "..Q."], ["..Q.", // 解法 2 "Q...", "...Q", ".Q.."] ] 解釋: 4 皇后問題存在兩個不同的解法。
ac的代碼,代碼註釋裏面有部分思路
public List<List<String>> solveNQueens(int n) {
List<List<String>> result = new ArrayList<>();
int[] x = new int[n];
reback(result, x, 0);
return result;
}
// 回溯算法
// 1、由於每一行一定都會有一個皇后,因此只需要一個x[n]便能確定每個皇后的位置,x數組記錄每一行的橫座標
// 2、一行一行向下遞歸,rowNum記錄行號
// 3、check方法對rowNum行的皇后位置進行校驗
public static void reback(List<List<String>> result, int[] x, int rowNum) {
if (rowNum == x.length) {
generateResult(result, x);
return;
}
int temp = x[rowNum];
for (int i = 0, length = x.length; i < length; i++) {
x[rowNum] = i;
if (check(x, rowNum)) {
reback(result, x, rowNum + 1);
}
x[rowNum] = temp;
}
}
// 校驗
// 0、只需要驗證到row的前一行(因爲只有row之前放皇后了)
// 1、x[i] == x[row] 校驗是否爲相同列
// 2、row - i == Math.abs(x[row] - x[i]) 校驗與主對角線和副對角線是否相同
public static boolean check(int[] x, int row) {
for (int i = 0; i < row; i++) {
if (x[i] == x[row] || row - i == Math.abs(x[row] - x[i])) {
return false;
}
}
return true;
}
//生成結果
public static void generateResult(List<List<String>> result, int[] x) {
List<String> temp = new ArrayList<>();
for (int i = 0,length = x.length; i < length; i++) {
StringBuffer stringBuffer = new StringBuffer();
for (int j = 0; j < length; j++) {
if(j != x[i]) {
stringBuffer.append('.');
continue;
}
stringBuffer.append('Q');
}
temp.add(stringBuffer.toString());
}
result.add(temp);
}