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;
}
};