一.题目要求
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
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
四.解题思路
N皇后问题在某种程度上可以看作是一种“升维”的全排列问题。在N皇后问题中,我们需要在一个N×N的棋盘上放置N个皇后,使得这些皇后不能相互攻击,即它们不能位于同一行、同一列或同一对角线上。如果我们将每个皇后的位置看作一个决策(即在某行放置一个皇后),那么这个问题就转化为了在每一行选取一个列位置来放置皇后,而且每一列只能选择一次。
全排列与N皇后的联系
全排列:在全排列问题中,我们需要对一个包含N个元素的集合进行排列,每个元素恰好出现一次,顺序可以不同。可以将N个元素的全排列看作是从N个位置中选取N个位置放置这N个元素,每个位置恰好使用一次。
N皇后问题:如果我们将每一行看作是选择的“元素”,将每一列看作是可选择的“位置”,那么在每一行选择一个列位置来放置皇后的过程,与全排列问题中从N个位置中选择位置来放置N个元素的过程相似。每一行选择一个列位置来放置皇后,确保每一列都恰好被选用一次,这就形成了一个排列。不过,N皇后问题还需要满足附加的约束条件——即放置的皇后之间不能互相攻击,这需要检查对角线方向的冲突。
对于升维的理解
将N皇后问题视为一种“升维”的全排列问题,是因为除了需要满足全排列的基本要求(每行放置一个皇后,且每列只能放置一个皇后,形成一个排列)之外,还需要额外满足不在同一对角线上的约束。这个额外的约束条件相当于在传统的全排列问题基础上增加了新的维度的考虑(即对角线的检查),使问题变得更加复杂。
五.代码实现
class Solution {
public:
bool checkCol(vector<vector<char>>& board, int row, int col) {
for (int i = 0; i < row; i++) {
if (board[i][col] == 'Q')
return false;
}
return true;
}
bool checkLT(vector<vector<char>>& board, int row, int col) {
for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
if (board[i][j] == 'Q')
return false;
}
return true;
}
bool checkRT(vector<vector<char>>& board, int row, int col) {
for (int i = row - 1, j = col + 1; i >= 0 && j < board.size(); i--, j++) {
if (board[i][j] == 'Q')
return false;
}
return true;
}
vector<vector<string>> solveNQueens(int n) {
vector<vector<char>> board(n, vector<char>(n, '.'));
vector<vector<string>> ans;
dfs(ans, board, 0, n);
return ans;
}
void dfs(vector<vector<string>>& ans, vector<vector<char>>& board, int row, int n)
{
if (row == n)
{
vector<string> oneAns;
for (int i = 0; i < n; i++)
{
string r;
for (int j = 0; j < n; j++)
{
r += board[i][j];
}
oneAns.push_back(r);
}
ans.push_back(oneAns);
}
for (int i = 0; i < n; i++)
{
if (checkCol(board, row, i) && checkLT(board, row, i) && checkRT(board, row, i))
{
board[row][i] = 'Q';
dfs(ans, board, row + 1, n);
board[row][i] = '.';
}
}
}
};
六.题目总结
–