和数独差不多,要注意的是,有些操作能省则省,可以省下不少时间。自己定义一个二维数组存n*n的棋盘会很方便。
检测当前能否填皇后的函数是要检查同一行同一列,以及左上45度以及右上45度,因为我们是从上往下填的,所以只需要判断上方的就行了。
如果到了递归边界,就通过该bord生成一个vector然后加入res,这样不用自己手动维护vector< string >了很方便。
dfs中就是遍历当前行的每一列看看能否填上Q,如果可以就填上,然后直接去下一行,这就是我说的省下来的操作,不用去下一列了,当前行已经不可能再填皇后了,保持原有的.就行了。
class Solution {
public:
bool isValid(int row, int col ,vector<vector<char>>& board){
int n = board.size();
for(int i = 0; i < n; ++i){
if(board[i][col] == 'Q') return false;
}
for(int i = row, j = col; i >= 0 && j >= 0; --i,--j){
if(board[i][j] == 'Q') return false;
}
for(int i = row, j = col; i >= 0 && j < n; --i, ++j){
if(board[i][j] == 'Q') return false;
}
return true;
}
vector<string> trans(vector<vector<char>>& board){
vector<string> v;
for(int i = 0; i < board.size(); ++i){
string x = "";
for(int j = 0; j < board[0].size(); ++j){
x += board[i][j];
}
v.push_back(x);
}
return v;
}
void dfs(int row, int col, vector<vector<char>>& board){
if(row == board.size()){
//这个时候将board里的拿出来作为一个vector返回
vector<string> t = trans(board);
res.push_back(t);
return;
}
//如果当前行到最后一列也不满足,直接return
for(int i = 0; i < board.size(); ++i){
if(isValid(row,i,board)){
board[row][i] = 'Q';
dfs(row+1,0,board);
board[row][i] = '.';
}
}
}
vector<vector<string>> solveNQueens(int n) {
vector<vector<char>> board(n,vector<char>(n,'.'));
dfs(0,0,board);
return res;
}
private:
vector<vector<string>> res;
};