问题:按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n
个皇后放置在 n×n
的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n
,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q'
和 '.'
分别代表了皇后和空位。
算法:
创建二维返回数组 ans ,皇后所在位置数组 col ,列占用数组 on_path ,左斜线占用数组 diag1 ,右斜线占用数组 diag2 。
找到斜线占用的规律:
进入 dfs 函数,从第一行开始,进入递归,遍历当前行的每一列,找到满足条件的,有两种选择,选这个位置或者不选。选这个位置,存入 col 数组,递归下一行。不选,恢复现场,注意,已经存入数据的 col 可以不用 pop_back(),因为可以直接覆盖。
代码:
class Solution {
public:
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> ans;// 返回数组ans
vector<int> col(n),on_path(n),diag1(n*2-1),diag2(n*2-1);
//行号r 列号c
auto dfs = [&](auto &&dfs,int r){
if(r == n){
vector<string> board(n);
for(int i = 0;i < n;i++) board[i] = string(col[i],'.') + 'Q' + string(n - 1 - col[i],'.');
ans.emplace_back(board);
return ;
}
for(int c = 0;c < n;c++){
int rc = r - c + n - 1;
if(!on_path[c] && !diag1[r+c] && !diag2[rc]){
col[r] = c;// col存储皇后所在位置
on_path[c] = diag1[r+c] = diag2[rc] = true;
dfs(dfs,r + 1);// 进入下一行
on_path[c] = diag1[r+c] = diag2[rc] = false;// 恢复现场
}
}
};
dfs(dfs,0);// 递归入口
return ans;
}
};