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个皇后。