八皇后问题参考这张图片:
51
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.."]
]
Subscribe to see which companies asked this question.
解法:
class Solution {
public:
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> res;
if(n < 0) return res;
vector<string> nqueue(n, string(n, '.'));
solve_nqueue(res, nqueue, 0, n);
return res;
}
private:
void solve_nqueue(vector<vector<string>>& res, vector<string>& nqueue, int row, int n) {
if(row == n){
res.push_back(nqueue);
return ;
}
for(int col=0; col<n; ++col){
if(is_valid(nqueue, row, col, n)){
nqueue[row][col] = 'Q';
solve_nqueue(res, nqueue, row+1, n);
nqueue[row][col] = '.';
}
}
}
bool is_valid(vector<string>& nqueue, int row, int col, int n){
for(int i=0; i<n; ++i){ //检查列
if(nqueue[i][col] == 'Q' && i != row)
return false;
}
for(int i=row-1, j=col-1; i>=0 && j>=0; --i, --j){ //检查135°
if(nqueue[i][j] == 'Q')
return false;
}
for(int i=row-1, j=col+1; i>=0 && j<n; --i, ++j){ //检查45°,所有的检查都只需要检查已填充的上半部分
if(nqueue[i][j] == 'Q')
return false;
}
return true;
}
};
51是要返回所有的结果,并且使用到了string。这里一个不常用的技巧就是vector< string>作为二维数组,也是很好用呢。
52
Follow up for N-Queens problem.
Now, instead outputting board configurations, return the total number of distinct solutions.
class Solution {
public:
int totalNQueens(int n) {
vector<int> nqueue(n, -1); //初始化为-1,不能为0,因为后面要用0
int counter = 0;
solve_nqueue(nqueue, 0, n, counter);
return counter;
}
private:
void solve_nqueue(vector<int>& nqueue, int row, int n, int& counter) {
if(row >= n) {
++counter;
return;
}
for(int col=0; col<n; ++col){
nqueue[row] = col;
if(is_valid(nqueue, row, n))
solve_nqueue(nqueue, row+1, n, counter);
}
}
bool is_valid(vector<int>& nqueue, int row, int n) {
for(int i=0; i<row; ++i){
if(abs(i-row) == abs(nqueue[i]-nqueue[row]) || abs(nqueue[i] == nqueue[row]))
return false;
}
return true;
}
};
52题只需要返回解法的个数,我使用了一个巧妙的解法,就是使用一维数组index表示row,nqueue[row]表示在该row行nqueue列放置皇后。
然后判断是否有效,使用了一个trick,详见: N皇后问题 –递归及回溯解决方案。