52. N-Queens II 回溯算法浅谈

来源:互联网 发布:三维b超单数据怎么看 编辑:程序博客网 时间:2024/06/14 14:28

Follow up for N-Queens problem.

Now, instead outputting board configurations, return the total number of distinct solutions.

Subscribe to see which companies asked this question

问题分析:

本题属于典型的回溯算法应用。一直对这种算法感觉有些似懂非懂,知道回溯算法的主旨是不停的试探,典型的DSP,当不满足解条件时,回退到上一层。看了清华的数据结构与算法对八皇后问题解答后更加迷惑,虽然栈是实现这种回退的比较好的容器,但实际上由于回溯算法的搜索过程是线性的,深度优先的遍历,其实个人觉得还是向量或者数组更合适,更简单的回退方法可以使问题简化。

static int x[1000];
class Solution {
private: void Backtrack(int t,int &sum,int n)
            {
                if(t==n) sum++;
                else
                {
                    for(int i=0;i<n;++i)
                    {
                        x[t]=i;
                        if(Place(t)) Backtrack(t+1,sum,n);
                    }
                }
            }
            bool Place(int t)
            {
                for(int i=0;i<t;++i)
                if(abs(i-t)==abs(x[i]-x[t])||(x[t]==x[i])) return false;
                return true;
            }
public:
    int totalNQueens(int n) {
        int sum=0;
        for(int i=0;i<n;++i)
        {
            x[0]=i;
            Backtrack(1,sum,n);
        }
        return sum;
    }
};

代码分析:首先定义了一个比较长的数组,其中x[i]表示第i个皇后,放在第i列,天然的不会发生不同皇后放在同一行的情况。需要回退的其他隐式条件为,两个皇后不能放在同一列(x[i]==x[k])以及不能放在对角线(等价于|i-k|==|x[i]-x[k]|)。在这两种情况下,需要发生回退。如Place中判断。对于第一个皇后来说,可能放的位置为(0—n-1)列,即x[0]=i,i=[0,n),由于第一个肯定不会冲突,下面都是从1开始试探,若已到达边界(sum++),回退回最开始,试探x[0],否则的话,从第0列开始试探当前的t(第一次为1),若不冲突,则试探t+1,否则当前的t为下一列。若所有都不满足,则回退到试探第0个皇后。

0 0