思路:每个皇后的同一行,同一列,同一斜线不能存在别的皇后。
经典解法为回溯递归,一层一层的向下扫描,需要用到一个pos数组,其中pos[i]表示第i行皇后的位置,初始化为-1,然后从第0行开始递归,每一行都一次遍历各列,判断如果在该位置放置皇后会不会有冲突,以此类推,当到最后一行的皇后放好后,一种解法就生成了,将其存入结果res中,然后再还会继续完成搜索所有的情况。
isValue 是判断在第row行,第col列放置皇后,是否满足。由于是一行一行的递归,所以只需检验和row之前的行,是否有冲突即可。col==pos[i]是判断列,abs(row-i)==abs(col-pos[i])是判断斜线。
solveNQueensDFS是逐行递归函数。若row=n,将pos中的皇后位置的数据,放入一个中间变量矩阵tmp中,并将tmp保存到ans中。若row!=n,则逐步判断满足在row行,满足皇后放置的位置,将其存取pos中,并递归到计算下一行皇后的位置。递归的下一步,要pos[row]=-1是为了不干扰其他情况的皇后位置。
最后在主函数 solveNQueens中,设置好初始条件了和返回值,即可解决NQueen的问题。
class Solution {
public:
bool isValue(vector<int> &pos,int row,int col)
{
for(int i=0;i<row;++i)
{
if(col==pos[i]||abs(row-i)==abs(col-pos[i])) return false;
}
return true;
}
void solveNQueensDFS(vector<int>&pos,int row,vector<vector<string> > &ans)
{
int n=pos.size();
if(row==n)
{
vector<string> tmp(n,string(n,'.'));
for(int i=0;i<n;++i) tmp[i][pos[i]]='Q';
ans.push_back(tmp);
}
else
{
for(int col=0;col<n;++col)
{
if(isValue(pos,row,col))
{
pos[row]=col;
solveNQueensDFS(pos,row+1,ans);
pos[row]=-1;
}
}
}
}
vector<vector<string>> solveNQueens(int n) {
vector<int>pos(n,-1);
vector<vector<string> >ans;
solveNQueensDFS(pos,0,ans);
return ans;
}
};