题目说明
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
示例 1:
输入:n = 4
输出:[[".Q…","…Q",“Q…”,"…Q."],["…Q.",“Q…”,"…Q",".Q…"]]
解释:如上图所示,4 皇后问题存在两个不同的解法。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/n-queens
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
回溯法解题
回溯法即对所有可能解的情况进行深度优先遍历,在使用回溯法之前需要找到约束条件,在本题中即任意两个皇后不能在同一行、同一列、同一斜线上(斜率为±1)。因此在进行深度优先遍历时,根据是否满足约束条件,决定是否继续向下遍历。
用大小为n的vector x存储位置信息,其中x[i]=j,即第i行第j列上放置皇后。
约束条件表示如下:
- 同一列:x[i]==x[j]
- 同一斜线:abs(x[i]-x[j])==abs(i-j)
采用递归回溯,实现代码如下:
class Solution {
public:
vector<int> x;//x[i]=j,即第i行第j列上放置皇后。
int nn;//存储皇后个数
vector<vector<string>> res;//存储所有满足条件的结果
bool Place(int k){//判断前k行的皇后放置是否满足约束条件。
for(int i=0;i<k;i++){
if((x[i]==x[k]) || (abs(x[i]-x[k])==abs(i-k)))
return false;
}
return true;
}
void generate(){//每种满足条件的情况调用该函数保存起来
vector<string> re;
for(int i=0;i<nn;i++){
string row = string(nn,'.');
row[x[i]]='Q';
re.push_back(row);
}
res.push_back(re);
}
void backtrack(int t){//递归函数,用来遍历第t层
if(t>=nn){//即满足情况
generate();
}
else{
for(int i=0;i<nn;i++){
x[t]=i;
if(t==0||Place(t))
backtrack(t+1);
}
}
}
vector<vector<string>> solveNQueens(int n) {
nn=n;
vector<int> temp(n);
x=temp;
backtrack(0);
return res;
}
};