N-Queens 问题,就是找出不同的N-Queens,我刚开始以为只是以为只要把第一行的Q放不同的位置,后面可能就固定了,于是思考的种类就少了,这其实在学栈的时候,就学过,思想就是,在栈里放入之前Q的位置,分别检查下一个要放入的位置是否和栈里所有的Q冲突,如果没有,则入栈,否则下一个,直到N-Queens放满为止,
下面的解法,只考虑了第一行的Q的不同位置,(后期有改进)
class Solution {
public:
bool check(stack<pair<int, int>> &sta, int cur_row, int cur_col)
{
stack<pair<int, int>> copy = sta;
while (!copy.empty())
{
auto cur = copy.top();
copy.pop();
if (cur.first == cur_row ||
cur.second == cur_col ||
(cur.second - cur.first) == (cur_col - cur_row ) ||
(cur.second + cur.first) == (cur_row + cur_col))
{
return false;
}
}
return true;
}
void push_dot(vector<string> &res, int row, int col)
{
for (int i = col; i < res.size(); ++i)
{
char var = '.';
res[row][col]= var;
}
}
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> solu;
int j = 0;
while(j<n)
{
int row = 0;
int col = 0;
int queen = 1;
stack<pair<int, int>> record;
string _module;
for(int i=0;i<n;++i)
{
_module+=".";
}
vector<string> res(n, _module);
char var = 'Q';
res[0][j] = var;
record.push(pair<int, int>(0, j));
push_dot(res, 0, j + 1);
col = 0;
row = 1;
while (row < n && col < n && queen <= n)
{
if (check(record, row, col)) {
record.push(pair<int, int>(row, col));
var = 'Q';
res[row][col] = var;
push_dot(res, row, col + 1);
col = 0;
row++;
queen++;
}
else {
if (col < n - 1) {
var = '.';
res[row][col++] = var;
}
else {
auto last = record.top();
row = last.first;
col = last.second;
var = '.';
res[row][col] = var;
queen--;
record.pop();
if (col < n - 1) col++;
else {
if (record.empty()) break;
row = record.top().first;
col = record.top().second;
var = '.';
res[row][col] = var;
col++;
queen--;
record.pop();
}
}
}
}
if (record.empty()) break;
while (record.size()>1)
{
record.pop();
}
auto a = record.top();
j = a.second+ 1;
solu.push_back(res);
}
return solu;
}
};
要考虑所有种情况,于是我就考虑了回溯法,让系统帮我压栈,的确会变慢很多 ,可能要让空间复杂度变低,则需要改成迭代法
class S1olution {
public:
bool check(stack<pair<int, int>> &sta, int cur_row, int cur_col)
{
stack<pair<int, int>> copy = sta;
while (!copy.empty())
{
auto cur = copy.top();
copy.pop();
if (cur.first == cur_row ||
cur.second == cur_col ||
(cur.second - cur.first) == (cur_col - cur_row ) ||
(cur.second + cur.first) == (cur_row + cur_col))
{
return false;
}
}
return true;
}
void push_dot(vector<string> &res, int row, int col)
{
for (int i = col; i < res.size(); ++i)
{
char var = '.';
res[row][col]= var;
}
}
void back_in(vector<vector<string>> &solu,vector<string> &res, int row, int col,stack<pair<int, int>> &record,int &queen)
{
int old = queen;
int n = res.size();
if (row == n) {
solu.push_back(res);
return ;
}
if (col == n) return ;
if (check(record, row, col)) {
record.push(pair<int, int>(row, col));
char var = 'Q';
res[row][col] = var;
queen++;
push_dot(res, row, col + 1);
back_in(solu, res, row + 1, 0, record, queen);
//此时下面为回溯
while (queen > old)
{
record.pop();
queen--;
}
var = '.';
res[row][col] = var;
back_in(solu, res, row, col + 1, record, queen);
//above
}
else {
char var = '.';
res[row][col] = var;
back_in(solu, res, row, ++col, record, queen);
}
}
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> solu;
stack<pair<int, int>> record;
string _module;
for (int i = 0; i < n; ++i)
{
_module += ".";
}
int queen = 0;
vector<string> res(n, _module);
back_in(solu, res, 0, 0, record,queen);
return solu;
}
};