n Queens n 皇后问题

89 阅读2分钟

image.png

N-Queens - LeetCode

52. N-Queens II

经典的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