题目描述
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
样例
输入: 4
输出: [
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。
算法1
(DFS暴力搜索) $O(n!)$
遍历每一行,并记录哪些列、哪些对角线已经被占据;
能填完$n$行的,就记录一下答案。
时间复杂度
只考虑列的互相约束,时间复杂度上界为$n!$,实际运算还会考虑对角线约束,复杂度会更低。
参考文献
C++ 代码
class Solution {
private:
vector<int> path;
vector<vector<string>> res;
vector<int> col, diag_s, diag_m;
public:
vector<vector<string>> solveNQueens(int n) {
if (n <= 0) return {};
col = vector<int>(n);
diag_s = vector<int>(2 * n - 1);
diag_m = vector<int>(2 * n - 1);
dfs(0, n);
return res;
}
void dfs(int r, const int &n){
if (r >= n){
vector<string> tmp(n, string(n,'.'));
for (int r = 0; r < n; ++r){
tmp[r][path[r]] = 'Q';
}
res.push_back(tmp);
return;
}
for (int c = 0; c < n; ++c){
if (!col[c] && !diag_s[r + c] && !diag_m[r - c + n - 1]){
col[c] = diag_s[r + c] = diag_m[r - c + n - 1] = true;
path.push_back(c);
dfs(r + 1, n);
path.pop_back();
col[c] = diag_s[r + c] = diag_m[r - c + n - 1] = false;
}
}
}
};