在 n×n 棋盤上放置 n 個皇后,使其互不攻擊(不同行、列、對角線)。返回所有合法擺放方案。
row 行col[row] 記錄該行皇后所在列row-1 行是否衝突row == n 時找到一個解新皇后 (row, col[row]) 與舊皇后 (i, col[i]):
col[row] == col[i]row - col[row] == i - col[i] → |col[row]-col[i]| == row-irow + col[row] == i + col[i] → 同樣由絕對值判斷public List<List<String>> solveNQueens(int n) {
List<List<String>> res = new ArrayList<>();
backtrack(n, 0, new int[n], res);
return res;
}
void backtrack(int n, int row, int[] col, List<List<String>> res) {
if (row == n) {
List<String> board = new ArrayList<>();
for (int i = 0; i < n; ++i) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < n; ++j)
sb.append(col[i] == j ? 'Q' : '.');
board.add(sb.toString());
}
res.add(board);
return;
}
for (int c = 0; c < n; ++c) {
col[row] = c;
if (valid(row, col))
backtrack(n, row + 1, col, res);
}
}
boolean valid(int row, int[] col) {
for (int i = 0; i < row; ++i)
if (col[row] == col[i] || Math.abs(col[row] - col[i]) == row - i)
return false;
return true;
}
void backtrack(State state) {
if (isSolution(state)) { save(state); return; }
for (Choice c : getChoices(state)) {
if (isValid(state, c)) {
apply(state, c);
backtrack(state);
undo(state, c); // 一維數組無需撤銷,蓋寫即可
}
}
}
此模板適用於: