N皇后 II

皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

给定一个整数 n,返回 n 皇后不同的解决方案的数量。

class Solution {
public:
    int totalNQueens(int n) {
        unordered_set<int> columns,diagonals1,diagonals2;
        return backtrack(n,0,columns,diagonals1,diagonals2);
    }

    int backtrack(int n,int row,unordered_set<int>& columns,unordered_set<int>& diagonals1,unordered_set<int>& diagonals2){
        if(row == n){
            return 1;
        }else{
            int count = 0;
            for(int i=0;i<n;i++){//i代表相应的列,对于每一行,都是对所有的列扫描一遍,并进行相应的剪枝
                if(columns.find(i)!=columns.end()){
                    continue;//如果所要找的列已经放过棋子
                }
                int diagonal1 = row - i;
                if(diagonals1.find(diagonal1) != diagonals1.end()){
                    continue;//对角线1
                }
                int diagonal2 = row + i;
                if(diagonals2.find(diagonal2) != diagonals2.end()){
                    continue;//对角线2
                }
                columns.insert(i);
                diagonals1.insert(diagonal1);
                diagonals2.insert(diagonal2);
                count += backtrack(n,row+1,columns,diagonals1,diagonals2);
                
                columns.erase(i);//回溯,第一行下完一个妻子后开始进行dfs,然后回溯重新下一个棋子,然后再次进行dfs
                diagonals1.erase(diagonal1);
                diagonals2.erase(diagonal2);
            }
            return count;
        }
    }
};

 

1.按照行为标准,对于每行而言依次落子。同时在每行落子的过程中,对每一列进行搜索剪枝。

2.需要注意的是,需要三个辅助数组,一个是columns来保证每行没有重复的元素,一个是diagonals1用来存储从左上到左下对角线的元素,需要注意的是如果位于一条对角线,则row - column的值是一个定值。diagonals2用来存储从左下到右上的元素,同理,如果位于一个对角线,则对应的和是一个定义,利用好着三个数组进行深度搜索即可。

3.注意三个数组的回溯过程,及时erase来保证程序的正确运行。

posted @ 2020-10-17 09:19  zmachine  阅读(114)  评论(0编辑  收藏  举报