# 题目
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n
个皇后放置在 n×n
的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n
,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q'
和 '.'
分别代表了皇后和空位。
输入:n = 4 | |
输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]] | |
解释:如上图所示,4 皇后问题存在两个不同的解法。 |
51. N 皇后 - 力扣(LeetCode)
# 分析
深度为 n 的 n 叉树
皇后们的约束条件:
- 不能同行
- 不能同列
- 不能同斜线
回溯三部曲:
1 函数参数
结果集 result,参数 n 棋盘大小
vector<vector<string>> result; | |
void backtracking(int n, int row, vector<string>& chessboard) { |
2 终止条件
最后一行停止
if (row == n) { | |
result.push_back(chessboard); | |
return; | |
} |
3 单层逻辑
for (int col = 0; col < n; col++) { | |
if (isValid(row, col, chessboard, n)) { // 验证合法就可以放 | |
chessboard[row][col] = 'Q'; // 放置皇后 | |
backtracking(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; | |
} |
完整代码
class Solution { | |
private: | |
vector<vector<string>> result; | |
//n 为输入的棋盘大小 | |
//row 是当前递归到棋盘的第几行了 | |
void backtracking(int n, int row, vector<string>& chessboard) { | |
if (row == n) { | |
result.push_back(chessboard); | |
return; | |
} | |
for (int col = 0; col < n; col++) { | |
if (isValid(row, col, chessboard, n)) { // 验证合法就可以放 | |
chessboard[row][col] = 'Q'; // 放置皇后 | |
backtracking(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; | |
} | |
public: | |
vector<vector<string>> solveNQueens(int n) { | |
result.clear(); | |
std::vector<std::string> chessboard(n, std::string(n, '.')); | |
backtracking(n, 0, chessboard); | |
return result; | |
} | |
}; |