n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
示例:
输入: 4
输出: [
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/n-queens
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
完整代码
基本思想
借助全排列的思想,在全排列的基础上增强条件。
-
定义代排列的数组nums,数组的元素为0……n,将数组全排列。
该数组表示在第i行的皇后位于第nums[i]列,这样就保证了皇后位于不同行不同列 -
在将当前排列结果存放到最终结果中时,进行判断,保证每两个皇后之间不能位于对角线上,如果满足条件就存入结果中,否则,不存入。
class Solution {
public:
vector<vector<string>> solveNQueens(int n) {
//皇后问题是指:皇后和皇后之间不同行,不同列,不在一条对角线上
//解决方案:全排列,去除在一条对角线上的情况
vector<vector<string>> res;
if(n < 1)
return res;
vector<int> nums(n);//用来指示第i行的皇后在第几列,每一列在(0……n)之间取值
for(int i = 0; i < n; ++i)
nums[i] = i;
change(nums, 0, res);
return res;
}
private:
void change(vector<int> nums, int s,vector<vector<string>> &res){
if(s == nums.size()){
int i, j;
for(i = 0; i < nums.size(); ++i){
for(j = i + 1; j < nums.size(); ++j){
if(nums[j] - nums [i] == j - i || nums[j] - nums [i] == i - j)
break;
}
if(j < nums.size())
break;
}
vector<string> cur;
if(i == nums.size()){
for(i = 0; i < nums.size(); ++i){
string t;
for(j = 0; j < nums.size(); ++j){
if(j == nums[i])
t += 'Q';
else
t += '.';
}
cur.push_back(t);
}
res.push_back(cur);
}
}
for(int i = s; i < nums.size(); ++i){
swap(nums[i], nums[s]);
change(nums, s + 1, res);
swap(nums[i], nums[s]);
}
}
void swap(int &a, int &b){
int t = a;
a = b;
b = t;
}
};