- N皇后 II
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给定一个整数 n,返回 n 皇后不同的解决方案的数量。
示例:
输入: 4
输出: 2
解释: 4 皇后问题存在如下两个不同的解法。
[
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
代码实现:
class Solution {
public:
int count;
int totalNQueens(int n) {
count = 0;
vector<int> colums(n);
backtracking(n,0,colums);
return count;
}
//回溯函数
void backtracking(int n,int row,vector<int>& colums){
//是否在所有n行都摆放好了皇后?
if(row == n){
count++;//如果是的,表明找到了新的摆放方法,计数加1
return;
}
//尝试着将皇后放置在当前行中的每一列
for(int col=0;col<n;++col){
colums[row] = col;
//检查是否合法,如果合法就继续到下一行
if(check(row,col,colums)){
backtracking(n,row+1,colums);
}
//如果不合法,就不要把皇后放在这列中(回溯)
colums[row]=-1;
}
}
//检查每行摆放的皇后是否合法
bool check(int row,int col,vector<int> colums){
for(int r=0;r<row;++r){//遍历每行
if(colums[r]==col || row-r==abs(colums[r]-col)){//正上方,和两侧斜对角线上不能有皇后
return false;
}
}
return true;
}
};
另一个版本(效果更好):
class Solution {
public:
bool valid(int n, vector<int>& cols) {
if (cols.size() <= 1)
return true;
int row = cols.size() - 1;
int col = cols.back();
for (int r = 0; r < row; ++r) {
int c = cols[r];
if (c == col || abs(c - col) == abs(r - row))
return false;
}
return true;
}
void backtrace(int n, vector<int>& cols, int& res) {
if (!valid(n, cols)) return;
if (cols.size() == n) {
++res;
return;
}
for (int i = 0; i < n; ++i) {
cols.push_back(i);
backtrace(n, cols, res);
cols.pop_back();
}
}
int totalNQueens(int n) {
vector<int> cols;
int res = 0;
backtrace(n, cols, res);
return res;
}
};