本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
51. N 皇后
来源:力扣(LeetCode)
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
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
解法
- 回溯:从每一行开始遍历,当前行开始按照列遍历,如果该行该列能够放该皇后,继续走下一层。这里需要准备三个集合来方便统计该列是否满足竖撇捺都符合要求;这里撇的关系是row+col, 捺是用row-col, 可以自己画图看看即可。
代码实现
回溯
python实现
class Solution:
def solveNQueens(self, n: int) -> List[List[str]]:
if n == 1:
return [['Q']]
self.cols = set()
self.pie = set()
self.na = set()
self.res = []
self.dfs(n, 0, [])
print(self.res)
return self._generate_res(n)
def dfs(self, n, row, current_state):
if row >= n:
self.res.append(current_state)
return
for col in range(n):
if col in self.cols or row+col in self.pie or row-col in self.na:
continue
self.cols.add(col)
self.pie.add(row+col)
self.na.add(row-col)
self.dfs(n, row+1, current_state+[col])
self.cols.remove(col)
self.pie.remove(row+col)
self.na.remove(row-col)
def _generate_res(self, n):
board = []
for res in self.res:
for col in res:
board.append('.'*col+'Q'+ '.'*(n-col-1))
# return [board[i:i+n] for i in range(0, len(board), n)]
return [board[i*n:(i+1)*n] for i in range(len(self.res))]
c++实现
class Solution {
vector<vector<int>> res;
set<int> cols;
set<int> pie;
set<int> na;
public:
void dfs(int n, int row, vector<int> current_state) {
if (row >= n) {
res.push_back(current_state);
return;
}
for (int col=0; col<n; col++) {
auto index1 = cols.find(col);
auto index2 = pie.find(row+col);
auto index3 = na.find(row-col);
if (index1 != cols.end() || index2 != pie.end() || index3 != na.end())
continue;
cols.insert(col);
pie.insert(row+col);
na.insert(row-col);
current_state.push_back(col);
dfs(n, row+1, current_state);
cols.erase(col);
pie.erase(row+col);
na.erase(row-col);
current_state.pop_back();
}
}
vector<vector<string>> solveNQueens(int n) {
if (n == 1)
return {{"Q"}};
dfs(n, 0, {});
vector<vector<string>> fin_res;
int len = res.size();
vector<string> board;
for(int i=0; i<len; i++) {
vector<int> tmp = res[i];
int len2 = tmp.size();
for (int j: tmp) {
string s;
for (int k = 0; k<j; k++) {
s += '.';
}
s += 'Q';
for (int l=j+1; l<n; l++) {
s += '.';
}
board.push_back(s);
}
}
for(int i=0; i<res.size(); i++) {
auto first = board.begin()+n*i;
auto last = board.begin() + n*(i+1);
vector<string> vec(first, last);
fin_res.push_back(vec);
}
return fin_res;
}
};
复杂度分析
- 时间复杂度:
- 空间复杂度: