原题链接:Leecode 52. N皇后 II
和这道题是一样的:Leecode 51. N 皇后 递归+回溯
1.朴素回溯
class Solution {
public:
// 解的数量
int res = 0;
// 检查在(row, col)位置放置皇后是否安全
bool issafe(int row, int col, vector<int>& board) {
// 遍历之前每一行的皇后
for (int i = 0; i < row; i++) {
if (board[i] == col)// 如果此行上的皇后在col列,和当前行冲突
return false;
else if (abs(i - row) == abs(board[i] - col))//如果对角线上存在皇后
return false;
}
// 如果没有冲突,返回true
return true;
}
void solve(int row, int n, vector<int>& board) {
// 如果已经放置完所有行,得到一个解
if (row == n) {
res++;
return;
}
// 尝试将皇后放置在当前行的每一个列中
for (int col = 0; col < n; col++) {
// 检查放置在当前位置是否安全
if (issafe(row, col, board)) {
// 如果安全,则在当前位置放置皇后
board[row] = col;
// 继续递归放置下一行的皇后
solve(row + 1, n, board);
// 回溯,将当前位置重新置为未放置皇后的状态,继续尝试下一个位置
board[row] = -1;
}
}
}
int totalNQueens(int n) {
// 使用一个长度为N的数组表示棋盘的状态,初始化为-1表示未放置皇后
vector<int> board(n, -1);
solve(0, n, board);
return res;
}
};
2.回溯+剪枝
class Solution {
public:
// 解的数量
int res = 0;
void solve(int row, int n, vector<int>& column, vector<int>& diagonal1,vector<int>& diagonal2) {
// 如果已经放置完所有行,得到一个解
if (row == n) {
res++;
return;
}
// 尝试将皇后放置在当前行的每一个列中
for (int col = 0; col < n; col++) {
// 检查放置在当前位置是否安全
if (column[col] || diagonal1[row - col + n - 1] || diagonal2[row + col])
continue;
// 如果安全,则在当前位置放置皇后
column[col] = diagonal1[row - col + n - 1] = diagonal2[row + col] = 1;
// 继续递归放置下一行的皇后
solve(row + 1, n, column, diagonal1, diagonal2);
// 回溯,将当前位置重新置为未放置皇后的状态,继续尝试下一个位置
column[col] = diagonal1[row - col + n - 1] = diagonal2[row + col] = 0;
}
}
int totalNQueens(int n) {
vector<int> column(n); // 列冲突数组
vector<int> diagonal1(2 * n - 1); // 左上-右下对角线冲突数组
vector<int> diagonal2(2 * n - 1); // 左上-右下对角线冲突数组
solve(0, n, column, diagonal1, diagonal2);
return res;
}
};
3.回溯+位运算
待更新