题目描述:
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
示例 1:输入:n = 4
输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解释:如上图所示,4 皇后问题存在两个不同的解法。
示例 2:输入:n = 1 输出:[["Q"]]
要使题目描述成立, 只需要DFS遍历每一行中的每一列即可, 如果该位置的行(col), 主对角线(dg), 副对角线(udg)均不存在皇后, 那么此位置就可以放置皇后。然后使用截距(b)的思想保存每一条对角线的状态(是否有皇后)。副对角线的截距为( y - x + n)是因为需要将截距转换为正数。
class Solution {
//定义结果变量
vector<vector<string>> ans;
//定义存储 列, 主对角线, 副对角线 是否有皇后的变量
vector<bool> col, dg, udg;
//定义 子结果变量(结果的一行)
vector<string> combine;
public:
vector<vector<string>> solveNQueens(int n) {
//初始化变量 n行
col = vector<bool>(n);
//2 * n 个对角线
dg = udg = vector<bool>(2 * n);
//将一行初始化为 "...."
combine = vector<string>(n,string(n,'.'));
//dfs深搜
dfs(n, 0);
return ans;
}
//dfs函数
void dfs(int n, int x) {
//走到最后一行, 将结果添加至ans
if(x == n) {
ans.push_back(combine);
return;
}
//遍历列
for(int y = 0; y < n; y++){
//列 主对角线 副对角线有皇后(跳过本列)
if(col[y] || dg[x + y] || udg[y - x + n]) continue;
//添加符合条件的该行的皇后
combine[x][y] = 'Q';
col[y] = dg[x + y] = udg[y - x + n] = true;
//dfs下一行
dfs(n, x + 1);
//搜索结束回退状态
combine[x][y] = '.';
col[y] = dg[x + y] = udg[y - x + n] = false;
}
}
};