分析:最直接的方法,即用二维数组表示一个棋盘,然后每次找寻合法的位置放置皇后。但是这个方法效率较低,因为每次查找合法的位置时都要使用循环,耗费大量的时间。可以消去这些循环查找合法位置所耗费的时间,即找出空闲的列,和斜线。斜线分上斜线与下斜线。每条上斜线上的格子,行加列为固定值,每条下斜线的格子,行减列为固定值。因此不再是检查空闲的格子,而是检查空闲的列和斜线,这可以根据传来的参数(列)立即确定,插入时也只是写入对列和斜线的控制,从而消去循环。然而八皇后问题本质上复杂度比指数还高,所以这种改进没有改变复杂度,但在同一个n下,可以减少计算量。
代码:
const int maxSize = 32;
class Solution {
public:
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> totalResult;
vector<string> aResult;
string temp;
initial(n);
for (int i = 0; i < n; ++i)
{
if (unguarded(i))
insert(i);
if (count == size)
{
for (int j = 0; j < size; ++j)
{
temp = "";
for (int k = 0; k < size; ++k)
{
if (k == queenInRow[j])
temp += 'Q';
else
temp += '.';
}
aResult.push_back(temp);
}
totalResult.push_back(aResult);
}
insert(i + 1);
remove(i);
}
return totalResult;
}
void initial(int n)
{
size = n;
count = 0;
resultNumber = 0;
for (int i = 0; i < maxSize; ++i) colFree[i] = true;
for (int i = 0; i < 2 * maxSize - 1; ++i) downFree[i] = true;
for (int i = 0; i < 2 * maxSize - 1; ++i) upFree[i] = true;
}
bool unguarded(int col) const
{
return colFree[col] && upFree[count + col] && downFree[count - col + size - 1];
}
void insert(int col)
{
queenInRow[count] = col;
colFree[col] = false;
upFree[count + col] = false;
downFree[count - col + size - 1] = false;
++count;
}
void remove(int col)
{
--count;
colFree[col] = true;
upFree[count + col] = true;
downFree[count - col + size - 1] = true;
}
private:
int size;
int count;
long resultNumber;
int queenInRow[maxSize];
bool colFree[maxSize];
bool downFree[2 * maxSize - 1];
bool upFree[2 * maxSize - 1];
};
测试通过: