前言
困难 ⚪ 主要是没想到行-列的差确认第二条斜线的关系。
题目
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
示例 1:

输入:n = 4 输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]] 解释:如上图所示,4 皇后问题存在两个不同的解法。
示例 2:
输入:n = 1 输出:[["Q"]]
提示:
1 <= n <= 9
思路
回溯法,定义三个哈希表分别记录列、行+列的和相等的斜线、行-列的差相等的斜线。遍历图的每个位置,如果不在列和两条斜线中,并入哈希表,并进入下一层递归(皇后数减一,行数加一)。直到只剩一个皇后且在最后一行。
我的题解
class Solution {
public:
vector<vector<string>> res;
vector<string> ans;
unordered_set<int> col;
unordered_set<int> slash_sum;
unordered_set<int> slash_dif;
int N;
void findans(int last, int i){
if (last <= 0)
return;
for (int j = 0; j < N; j++){
if (!col.count(j) && !slash_sum.count(i+j) && !slash_dif.count(i-j)){
col.insert(j);
slash_sum.insert(i+j);
slash_dif.insert(i-j);
ans[i][j] = 'Q';
if (i == N-1 && last == 1){
res.push_back(ans);
}
findans(last-1, i+1);
ans[i][j] = '.';
col.erase(j);
slash_sum.erase(i+j);
slash_dif.erase(i-j);
}
}
}
vector<vector<string>> solveNQueens(int n) {
N = n;
ans = vector<string>(N, string(N, '.'));
findans(N, 0);
return res;
}
};
官方题解
基于集合的回溯与笔者基本一致
位运算有点复杂此处略...
知识点
初始化 ans = vector<string>(N, string(N, '.'));
心得
此题关键在于如何定义斜线,知道了之后整个题就迎刃而解了,典型回溯法。
773

被折叠的 条评论
为什么被折叠?



