Leetcode-n皇后

题目描述

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。

n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。

每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q''.' 分别代表了皇后和空位。

示例

image-20240731172857954

输入:n = 4

输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]

解释:如上图所示,4 皇后问题存在两个不同的解法。

1 <= n <= 9

思路

经典的回溯问题。

定义数组Q存储已经放皇后的位置\((i, Q[i])\)

根据row进行回溯,判断皇后放在\([1,n]\) col是否有效,执行路径如下:

image-20240731173548183

AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Solution {
public:
vector<int> Q;
vector<vector<string>> ans;

bool check(int x, int y){
for(int i = 0; i<Q.size(); i++){
if(Q[i] == y || abs(i - x) == abs(Q[i] - y)) return false;
}
return true;

}

void dfs(int row, int n){
if(row >= n){
vector<string> temp(n, string(n, '.'));
for(int i = 0; i<Q.size(); i++) temp[i][Q[i]] = 'Q';
ans.push_back(temp);
return;
}

for(int i=0; i<n; i++){
if(check(row, i)){
Q.push_back(i);
dfs(row+1, n);
Q.pop_back();
}
}
}

vector<vector<string>> solveNQueens(int n) {
dfs(0, n);
return ans;
}
};

复杂度分析

  • 时间复杂度:\(O(n!)\)。搜索树中至多有 \(O(n!)\) 个叶子。
  • 空间复杂度:O(n)。返回值的空间不计入。