经典的DFS题。书54(有问题看书)
八皇后问题:在棋盘上放置8个皇后,使得它们不同行,不同列,不同对角线,n皇后是八皇后问题的拓展。
其实整体思路非常简单,就是摆明所有情况,如果情况符合,则推入解,如果不符合,这条线废弃。因为我们把所有的可能性都摆出来,所以Time Complexity is O(n * n!) check() 的时间复杂度是O(n), DFS()因为是一行一行的放置皇后,由于每个皇后必须位于不同列,因此已经放置的皇后所在的列不能放置别的皇后。第一个皇后有 N 列可以选择,第二个皇后最多有 N−1 列可以选择,第三个皇后最多有 N−2 列可以选择(如果考虑到不能在同一条斜线上,可能的选择数量更少),因此所有可能的情况不会超过 N! 种,遍历这些情况的时间复杂度是 O(N!)。加起来时间复杂度是O(n * n!). 但因为n < 12 所以 Time Complexity 也可以看成是 O(n!).
思路:
每行每行的放,放置的地方用col[i]记录。新一行的[col][row]和之前每一个旧的[col][row] 也就是(col[i],i) (0 <= i < r) 比如到了第四行,那就是前三行做对比。如果可以放,则放(然后开始新的dfs),如果一行结束了都没合适的放的地方,则说明这个解不对。在每个解中,每行有且只有一个Queen。
LeetCode 51 题解
class Solution {
int tot;
int col[12];
vector<vector<string>> ans;
public:
bool check(int c, int r){
for(int i = 0; i < r; i++){
if(col[i] == c || (abs(col[i] - c) == abs(i-r))){
return false;
}
}
return true;
}
void DFS(int r, int n, vector<string> temp){
if(n == r){
ans.push_back(temp);
return; //must return after pushing the solution to the answer
}
for(int c = 0; c < n; c++){
if(check(c, r)){
temp[r][c] = 'Q';
col[r] = c;
DFS(r+1, n, temp);
temp[r][c] = '.';//Reset to original status after recursive call
}
}
}
vector<vector<string>> solveNQueens(int n) {
if(n == 1) return {{"Q"}};
if(n == 2 || n ==3 ) return {};
tot = 0;
fill(begin(col), end(col), 0); //initialize the col array to 0
//每一行先预设好
string row(n, '.');
vector<string> temp(n, row);
DFS(0, n, temp);
return ans;
}
};
第一遍的小错误:
fill(begin(col), end(col), 0);
return;
temp[r][c] = '.';//Reset to original status after recursive call