问题描述:Leetcode 51和52
n皇后问题是指在一个n*n的棋盘上放置n个皇后,使其满足n个皇后之间不能相互攻击:没有两个皇后同时在棋盘的同一行或者同一列或者同一条斜线上。
适用方法:回溯法,回溯法意即从一个点往前走,满足条件继续往前走,不能满足某个要求的话回退回来,试其他的路径。
对于n皇后问题来说回溯法体现在:从当前行开始,从第0列开始搜索,直到找到某列上可以放置皇后,那么继续下一行从第0列搜索。如果当前列上找不到可以放置皇后的列,则回溯至当前行的上一行,将其上的皇后从它所在的列向后搜索,如果回溯到的上一列向后搜索后找不到可以放置,则继续向上回溯,继续搜索,如果直到第一行上也找不到可以放置皇后的位置,那么程序终止。如果到最后一行,找到可以放置皇后的位置,记录当前的这个解,并在最后一行当前列的下一列继续搜索。(最后这句话可以这么理解,找到一个解后由于要找所有的解,找当前列的下一个位置,如果不能满足的话我们就要向上回溯,那么其实就相当于最后一行之上的各行皇后的布局发生了变化,然后我们再在最后一行进行搜索,这其实就相当于查找所有的n-Queens的解)。
n皇后问题使用一个一维数组的数据结A[n]构即可,一维数组的下标表示当前行,其对应的元素值表示当前行皇后所在的列。这样的一种数据结构保证了所有的皇后不在不一行,那么检测的时候只需进行列和斜线检测即可。对于列上检测时,如果检测当前行(记作row)的第j列,那么只需要判断当前行之上的各行,用i表示,皇后位置是否在第j列,即判断A[i]是否等于j。对于斜线上的检测,牛人们发现如果abs(row - i)== abs(j - A[i]),那么斜线上存在冲突。之所以是只对当前行之上的各行进行检测,是因为我们当前行的皇后位置确定了我们才进行其下各行的皇后位置确定。
n皇后主要的两种方法:
1. iterative
这种方法充分的体现了回溯法的本质。这个方法来自这篇博客 http://blog.csdn.net/hackbuteer1/article/details/6657109
class Solution {
public:
void add_answer(vector<vector<string> > &result,vector<int> &answer)
{
vector<string> one_answer;
char *row = new char[answer.size() + 1];
for(int i