LeetCode 52. N皇后 II
阿新 • • 發佈:2021-04-03
難度:困難。
標籤:
可以使用第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;
}
};
結果: