ps:皇后可以攻击同一行、同一列以及左上角、右上角、左下角、右下角这些角度方向上的任意单位。
时间复杂度:O(n!)
class Solution {
public:
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>>res;
vector<vector<int>>board(n, vector<int>(n, 0));//0表示无皇后,1表示有皇后
DFS(n, 0, board, res);//一行一行地放皇后
return res;
}
void DFS(int n, int row, vector<vector<int>>&board, vector<vector<string>>&res)
{
//0~n-1都填写完毕
if (row == n)
{
vector<string>track = generate_track(n, board);
res.push_back(track);
return;
}
for (int col = 0; col < n; col++)
{
if (isUsable(board, row, col, n))
{
board[row][col] = 1;
//填写下一行
DFS(n, row + 1, board, res);
board[row][col] = 0;//回溯
}
}
}
//board[row][col]是否可用
bool isUsable(vector<vector<int>>&board, int row, int col, int n) {
//检查第col列上有无皇后
for (int i = 0; i <= row - 1; i++)
{
if (board[i][col] == 1)return false;
}
//检查左上至右下对角线有无皇后
for (int i = col - 1; i >= 0; i--)
{
if (i + row - col < 0)break;
if (board[i + row - col][i] == 1)return false;
}
//检查右上至左下对角线有无皇后
for (int i = col + 1; i < n; i++) {
if (row + col - i < 0)break;
if (board[row + col - i][i] == 1)return false;
}
return true;
}
vector<string> generate_track(int n, vector<vector<int>>&board)
{
vector<string>track;
for (int i = 0; i < n; i++)
{
string s = "";
for (int j = 0; j < n; j++)
{
if (board[i][j] == 0)
s += '.';
else
s += 'Q';
}
track.push_back(s);
}
return track;
}
};
更加简单了,直接求count即可。
class Solution {
public:
int totalNQueens(int n) {
vector<vector<int>>board(n, vector<int>(n, 0));//0表示无皇后,1表示有皇后
DFS(n, 0, board);//一行一行地放皇后
return count;
}
void DFS(int n, int row, vector<vector<int>>&board)
{
//0~n-1都填写完毕
if (row == n)
{
count++;
return;
}
for (int col = 0; col < n; col++)
{
if (isUsable(board, row, col, n))
{
board[row][col] = 1;
//填写下一行
DFS(n, row + 1, board);
board[row][col] = 0;//回溯
}
}
}
//board[row][col]是否可用
bool isUsable(vector<vector<int>>&board, int row, int col, int n) {
//检查第col列上有无皇后
for (int i = 0; i <= row - 1; i++)
{
if (board[i][col] == 1)return false;
}
//检查左上至右下对角线有无皇后
for (int i = col - 1; i >= 0; i--)
{
if (i + row - col < 0)break;
if (board[i + row - col][i] == 1)return false;
}
//检查右上至左下对角线有无皇后
for (int i = col + 1; i < n; i++) {
if (row + col - i < 0)break;
if (board[row + col - i][i] == 1)return false;
}
return true;
}
private:
int count = 0;
};