n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
示例:
输入: 4
输出: [
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。
回溯问题的套路可以参考:https://leetcode-cn.com/problems/n-queens/solution/hui-su-suan-fa-xiang-jie-by-labuladong/
这里有几个要点,撇是是row+col=常数,捺是row-col=常数,为了避免减出来是负数,使用set来记录已经被皇后攻击的撇捺。我们按行进行遍历,当最后一行执行完毕,说明所有的结果已经产生
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;
class Solution {
// output
List<List<String>> res = new ArrayList();
Set<Integer> col = new HashSet<>();
Set<Integer> na = new HashSet<>();
Set<Integer> pie = new HashSet<>();
private int n;
public List<List<String>> solveNQueens(int n) {
this.n = n;
Stack<Integer> stack = new Stack<>();
backtrack(stack,0);
return res;
}
public void backtrack(Stack<Integer> stack, int row){
if(n==row){
//生成结果
List<String> board = convert2board(stack, n);
res.add(board);
return;
}
// 针对每一列,尝试是否可以放置
for (int colunm = 0; colunm < n; colunm++) {
if (!col.contains(colunm) && !pie.contains(row + colunm) && !na.contains(row - colunm)) {
stack.add(colunm);
col.add(colunm);
pie.add(row + colunm);
na.add(row - colunm);
backtrack(stack,row+1);
na.remove(row - colunm);
pie.remove(row + colunm);
col.remove(colunm);
stack.pop();
}
}
}
private List<String> convert2board(Stack<Integer> stack, int n) {
List<String> board = new ArrayList<>();
for (Integer num : stack) {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < n; i++) {
stringBuilder.append(".");
}
stringBuilder.replace(num, num + 1, "Q");
board.add(stringBuilder.toString());
}
return board;
}
}