题目:
-
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
-
n 皇后问题 研究的是如何将
n
个皇后放置在n×n
的棋盘上,并且使皇后彼此之间不能相互攻击。 -
给你一个整数
n
,返回所有不同的 n 皇后问题 的解决方案。 -
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中
'Q'
和'.'
分别代表了皇后和空位。
示例:
- 输入: n = 4 n = 4 n=4
- 输出: [ [ " . Q . . " , " . . . Q " , " Q . . . " , " . . Q . " ] , [ " . . Q . " , " Q . . . " , " . . . Q " , " . Q . . " ] ] [[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]] [[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
- 解释: 如上图所示,4 皇后问题存在两个不同的解法。
解题思路:
首先定义结果集res
,用来存放所有解决方案。然后dfs(深度优先搜索算法)
每一行,每dfs
一行,遍历当前行的所有列,是否有合法位置,也就是满足三个条件,行、列、斜线
是否已有皇后,若有则跳过不放置,否则就将该位置置为皇后'Q'
。
class Solution {
public:
vector<vector<string>> res;
void dfs(int n, int row, vector<string>& chessBoard){
// 当遍历完所有行,代表有了一个解决方案,加入到结果集中
if(row == n){
res.push_back(chessBoard);
return;
}
// 遍历当前行的所有列
for(int col = 0; col < n; col++){
// 检查当前位置是否可以放置皇后
if(isValid(row, col, chessBoard, n)){
// 放置皇后
chessBoard[row][col] = 'Q';
// dfs到下一行
dfs(n, row + 1, chessBoard);
// 回溯,恢复现场
chessBoard[row][col] = '.';
}
}
}
bool isValid(int row, int col, vector<string>& chessBoard, int n){
// 遍历列,检查是否有皇后
for(int i = 0; i < row; i++){
if(chessBoard[i][col] == 'Q') return false;
}
// 遍历45°角是否有皇后
for(int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--){
if(chessBoard[i][j] == 'Q') return false;
}
// 遍历135°角是否有皇后
for(int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++){
if(chessBoard[i][j] == 'Q') return false;
}
return true;
}
vector<vector<string>> solveNQueens(int n) {
// 定义棋盘,默认都为'.'
vector<string> chessBoard(n, string(n, '.'));
// 从第0行开始dfs
dfs(n, 0, chessBoard);
return res;
}
};