难度:困难。
标签:
可以使用第51题的解法来做。
正确解法:
class Solution {
int result = 0;
bool place(int t, vector<int> x){
for(int i = 0; i < t; i++){
if(abs(x[t] - x[i]) == abs(t - i) || x[t] == x[i]){
return false;
}
}
return true;
}
void backtrace(int n, int t, vector<int>& x){
if(t >= n){
result++;
return;
}
for(int i = 0; i < n; i++){
x[t] = i;
if(place(t, x))backtrace(n, t + 1, x);
}
}
public:
int totalNQueens(int n) {
vector<int> x(n);
backtrace(n, 0, x);
return result;
}
};
但这种方法效率很低,结果:
参考官方题解,可以使用基于集合的回溯方法。
使用三个数组 c o l u m n s columns columns、 d i a g o n a l s 1 diagonals_1 diagonals1和 d i a g o n a l s 2 diagonals_2 diagonals2来分别表示每一列和两个方向的每条斜线上是否有皇后。
- 列相同时,列的索引相同。
- 从左上到右下的斜线相同时,行索引和列索引之差相同。
- 从右上到左下的斜线相同时,行索引和列索引之和相同。
因此,每次放置皇后时,判断当前位置所在的列和两个斜线上是否有皇后,没有就可以放置。
正确解法:
class Solution {
int result = 0;
bool place(int j, int k1, int k2, vector<int>& columns, vector<int>& diagonals1, vector<int>& diagonals2){
if(columns[j] == 0 && diagonals1[k1] == 0 && diagonals2[k2] == 0){
columns[j] = 1;
diagonals1[k1] = 1;
diagonals2[k2] = 1;
return true;
}
return false;
}
void backtrace(int n, int t, vector<int>& columns, vector<int>& diagonals1, vector<int>& diagonals2){
if(t >= n){
result++;
return;
}
for(int i = 0; i < n; i++){
int k1 = i - t + n - 1, k2 = t + i;
if(place(i, k1, k2, columns, diagonals1, diagonals2)){
backtrace(n, t + 1, columns, diagonals1, diagonals2);
columns[i] = 0;
diagonals1[k1] = 0;
diagonals2[k2] = 0;
}
}
}
public:
int totalNQueens(int n) {
vector<int> columns(n), diagonals1(2 * n - 1), diagonals2(2 * n - 1);
backtrace(n, 0, columns, diagonals1, diagonals2);
return result;
}
};
结果: