题目:
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..”]
]
题意:该题是n皇后问题,即任意两个皇后都不能处于同一行、同一列或同一斜线上。
思路:很明显每一行每一列都只能有一个皇后,否则一行中出现两个皇后或者一列中出现两个皇后,她们就可以互相攻击了。还需要满足的条件是任意两个皇后不在同一列上。
该题采用回溯的方法,与前面字符串的全排列类似。有n个皇后就用一个一维数组A[n]表示,初始化时A[i] = i;代表的意思是第i行的皇后在第i列。第一行的皇后所在的列可能是第1到第n列(比如选择了第k列),那么第二行的皇后有n-1个列可以选,只要不在第k列,以此类推。每一行确定一个皇后的列的位置的时候需要判断与前面确定的皇后是否在一个斜线上,不在的话才会递归到下一行。
class Solution {
public:
vector<vector<string> > solveNQueens(int n) {
vector<vector<string>> result;
if(n <= 0)return result;
else if(n == 1){
vector<string> temp;
temp.push_back("Q");
result.push_back(temp);
return result;
}
vector<int> QueenInRows;
vector<string> res;
for(int i = 0; i < n ; i++){
QueenInRows.push_back(i);
res.push_back(string(n,'.'));
res[i][i] = 'Q';
}
getAllResult(result,0,QueenInRows,res);
return result;
}
void getAllResult(vector<vector<string>>& result,int i, vector<int>& QueenInRows,vector<string> & temp){
if(i == QueenInRows.size() - 1){
for(int k = 0; k < i; k++)
if(abs(QueenInRows[k] - QueenInRows[i]) == abs(i-k))return;//判断最后一行的皇后是否与其他行的皇后在同一条斜线上。
result.push_back(temp);
return;
}
for(int j = i; j < QueenInRows.size(); j++){
swap(QueenInRows[i],QueenInRows[j]);
bool goout = false;
for(int k = 0; k < i; k++){//判断该行的皇后放置的列的位置是否与其他行的皇后在同一条斜线上。
if(abs(QueenInRows[k] - QueenInRows[i]) == abs(i-k)){
swap(QueenInRows[i],QueenInRows[j]);
goout = true;
break;
}
}
if(goout)continue;
swap(temp[i],temp[j]);
getAllResult(result,i+1,QueenInRows,temp);
swap(QueenInRows[i],QueenInRows[j]);
swap(temp[i],temp[j]);
}
}
};