设计一种算法,打印 N 皇后在 N × N 棋盘上的各种摆法,其中每个皇后都不同行、不同列,也不在对角线上。这里的“对角线”指的是所有的对角线,不只是平分整个棋盘的那两条对角线。
注意:本题相对原题做了扩展
示例:
输入:4 输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]] 解释: 4 皇后问题存在如下两个不同的解法。 [ [".Q..", // 解法 1 "...Q", "Q...", "..Q."], ["..Q.", // 解法 2 "Q...", "...Q", ".Q.."] ]
深度优先搜索 + 剪枝。
class Solution:
def solveNQueens(self, n: int) -> List[List[str]]:
res = []
g = [['.'] * n for _ in range(n)]
col = [False] * n
dg = [False] * (2 * n)
udg = [False] * (2 * n)
def dfs(u):
if u == n:
res.append([''.join(item) for item in g])
return
for i in range(n):
if not col[i] and not dg[u + i] and not udg[n - u + i]:
g[u][i] = 'Q'
col[i] = dg[u + i] = udg[n - u + i] = True
dfs(u + 1)
g[u][i] = '.'
col[i] = dg[u + i] = udg[n - u + i] = False
dfs(0)
return res
class Solution {
public List<List<String>> solveNQueens(int n) {
List<List<String>> res = new ArrayList<>();
String[][] g = new String[n][n];
for (int i = 0; i < n; ++i) {
String[] t = new String[n];
Arrays.fill(t, ".");
g[i] = t;
}
// 列是否已经有值
boolean[] col = new boolean[n];
// 斜线是否已经有值
boolean[] dg = new boolean[2 * n];
// 反斜线是否已经有值
boolean[] udg = new boolean[2 * n];
// 从第一行开始搜索
dfs(0, n, col, dg, udg, g, res);
return res;
}
private void dfs(int u, int n, boolean[] col, boolean[] dg, boolean[] udg, String[][] g,
List<List<String>> res) {
if (u == n) {
List<String> t = new ArrayList<>();
for (String[] e : g) {
t.add(String.join("", e));
}
res.add(t);
return;
}
for (int i = 0; i < n; ++i) {
if (!col[i] && !dg[u + i] && !udg[n - u + i]) {
g[u][i] = "Q";
col[i] = dg[u + i] = udg[n - u + i] = true;
dfs(u + 1, n, col, dg, udg, g, res);
g[u][i] = ".";
col[i] = dg[u + i] = udg[n - u + i] = false;
}
}
}
}
class Solution {
public:
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> res;
vector<string> g(n, string(n, '.'));
vector<bool> col(n, false);
vector<bool> dg(2 * n, false);
vector<bool> udg(2 * n, false);
dfs(0, n, col, dg, udg, g, res);
return res;
}
void dfs(int u, int n, vector<bool>& col, vector<bool>& dg, vector<bool>& udg, vector<string>& g, vector<vector<string>>& res) {
if (u == n) {
res.push_back(g);
return;
}
for (int i = 0; i < n; ++i) {
if (!col[i] && !dg[u + i] && !udg[n - u + i]) {
g[u][i] = 'Q';
col[i] = dg[u + i] = udg[n - u + i] = true;
dfs(u + 1, n, col, dg, udg, g, res);
g[u][i] = '.';
col[i] = dg[u + i] = udg[n - u + i] = false;
}
}
}
};
func solveNQueens(n int) [][]string {
res := [][]string{}
g := make([][]string, n)
for i := range g {
g[i] = make([]string, n)
for j := range g[i] {
g[i][j] = "."
}
}
col := make([]bool, n)
dg := make([]bool, 2*n)
udg := make([]bool, 2*n)
dfs(0, n, col, dg, udg, g, &res)
return res
}
func dfs(u, n int, col, dg, udg []bool, g [][]string, res *[][]string) {
if u == n {
t := make([]string, n)
for i := 0; i < n; i++ {
t[i] = strings.Join(g[i], "")
}
*res = append(*res, t)
return
}
for i := 0; i < n; i++ {
if !col[i] && !dg[u+i] && !udg[n-u+i] {
g[u][i] = "Q"
col[i], dg[u+i], udg[n-u+i] = true, true, true
dfs(u+1, n, col, dg, udg, g, res)
g[u][i] = "."
col[i], dg[u+i], udg[n-u+i] = false, false, false
}
}
}