题目:
The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.
Given an integer n, return all distinct solutions to the n-queens puzzle.
Each solution contains a distinct board configuration of the n-queens' placement, where 'Q'
and '.'
both indicate a queen and an empty space respectively.
For example,
There exist two distinct solutions to the 4-queens puzzle:
[ [".Q..", // Solution 1 "...Q", "Q...", "..Q."], ["..Q.", // Solution 2 "Q...", "...Q", ".Q.."] ]
题目中 no two queens attack each other 意味着两个皇后不在同行同列或者斜率为1的斜线上,或者从一个数组的角度来看
Solution1的数组形式是1302 Solution2的数组形式是2031 即相邻的两个数之间相差大于1
主要思路是采用递归,如果某行放置的位置不与前面的冲突,那么此行就是可以放置的,然后递归到后面的行
class Solution {
public:
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> res;
vector<int> num(n);
solve(res,num,0,n);
return res;
}
void solve(vector<vector<string>> &res,vector<int> &num,int s,int n){
if(s==n){
vector<string> temp(n,string(n,'.'));
for(int i=0;i<n;++i)
temp[i][num[i]]='Q';
res.push_back(temp);
return;
}
for(num[s]=0;num[s]<n;num[s]++){//num数组表示每行Q的位置
if(safe(num,s,n))
solve(res,num,s+1,n);
}
return;
}
bool safe(vector<int> &num,int s,int n){
for(int i=0;i<s;i++){
if(num[i]==num[s]||abs(s-i)==abs(num[s]-num[i]))//判断皇后的位置是否可以放置
return false;
}
return true;
}
};
------------------------------------------------------------第二遍重刷-------------------------------
八皇后的问题与数独问题十分相似,解法也相似,典型的回溯法:
class Solution {
public:
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> ret;
vector<string> nqueens(n,string(n,'.'));
solveNQueens(ret,nqueens,0,n);
return ret;
}
void solveNQueens(vector<vector<string>> &ret,vector<string> &nqueens,int row,int& n){
if(row==n){
ret.push_back(nqueens);
return ;
}
for(int col=0;col<n;++col){
if(isValid(nqueens,row,col,n)){
nqueens[row][col]='Q';
solveNQueens(ret,nqueens,row+1,n);
nqueens[row][col]='.';
}
}
}
bool isValid(vector<string> &nqueens,int row,int col,int n){
for (int i = 0; i != row; ++i)
if (nqueens[i][col] == 'Q')
return false;
for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; --i, --j)
if (nqueens[i][j] == 'Q')
return false;
//check if the 135° diagonal had a queen before.
for (int i = row - 1, j = col + 1; i >= 0 && j < n; --i, ++j)
if (nqueens[i][j] == 'Q')
return false;
return true;
}
};