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.."] ]比较简洁的DFS代码,参考 http://blog.csdn.net/linhuanmars/article/details/20667175。时间O(n!),空间O(n)。注意判断两个元素是否在同一对角线的技巧,使用abs。
class Solution {
public:
vector<vector<string> > solveNQueens(int n) {
vector<vector<string> > result;
vector<int> colForRow(n);
dfs(n, 0, colForRow, result);
return result;
}
void dfs(int n, int curline, vector<int> &colForRow, vector<vector<string> > &result)
{
if(curline == n)
{
vector<string> out;
for(int i=0; i<n; i++)
{
string line;
for(int j=0; j<n; j++)
{
if(colForRow[i] == j)
line += "Q";
else
line += ".";
}
out.push_back(line);
}
result.push_back(out);
}
else
{
for(int i=0; i<n; i++)
{
colForRow[curline] = i;
if(check(curline, colForRow))
dfs(n, curline+1, colForRow, result);
}
}
}
bool check(int curline, vector<int> &colForRow)
{
for(int i=0; i<curline; i++)
{
if(colForRow[i] == colForRow[curline] ||
(abs(colForRow[i]-colForRow[curline]) == abs(curline-i)))
return false;
}
return true;
}
};
非递归DSF实现。参考:http://blog.csdn.net/starmsg/article/details/39085143
class Solution {
public:
vector<vector<string> > solveNQueens(int n) {
vector<vector<string> > result;
for(int i=0; i<n; i++)
{
dfsWithStack(result, i, n);
}
return result;
}
void dfsWithStack(vector<vector<string> > &result, int firstPlace, int n)
{
stack<int> s;
vector<int> path;
s.push(firstPlace);
while(!s.empty())
{
int place = s.top();
path.push_back(place);
if(path.size() == n)
{
vector<string> res;
for(int i=0; i<n; i++)
res.push_back(genString(path[i], n));
result.push_back(res);
}
//push adjacent to to stack
if(path.size() < n)
{
for(int i=0; i<n; i++)
{
if(valid(i, path)) s.push(i);
}
}
while (!s.empty() && s.top() == path.back())
{
s.pop();
path.pop_back();
}
}
}
string genString(int place, int n)
{
string res;
for(int i=0; i<n; i++)
{
res += (i==place)?"Q" : ".";
}
return res;
}
bool valid(int candidate, vector<int> path)
{
int nextline = path.size();
for(int i=0; i<path.size(); i++)
{
if(candidate == path[i])
return false;
if(abs(candidate-path[i]) == (path.size()-i))
return false;
}
return true;
}
};