题目描述
N-Queens
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.."]
]
N-Queens II
就是返回方案个数。
题目分析
n后问题是一个典型的回溯遍历的问题。如果减少遍历次数就成了问题的关键。
问题的核心就在于检测一个位置是否可行。
我们用一个数组A[i]来表示第i个皇后所处的位置。
那么A[i]是否合理的判断标准就是i之前的所有皇后都和i不是同一列(同一行是不可能的,因为这是i行)和同一斜线上。
在同一斜线的条件是(abs(k-i) == abs(A[k] - A[i]))
这样就得出一个判断函数
bool check(vector<int> &A,int k)
{
for(int i = 0;i<k;i++)
if(abs(k-i) == abs(A[k] - A[i]) || A[k] == A[i]) return false;
return true;
}
{
for(int i = 0;i<k;i++)
if(abs(k-i) == abs(A[k] - A[i]) || A[k] == A[i]) return false;
return true;
}
下面给出递归的迭代两种思路的代码。
代码示例
class Solution {
public:
int totalNQueens(int n) {
int ret = 0;
vector<int> A(n,-1);
int row = 0;
while(row >= 0)
{
A[row]++;
while(A[row]<n && !check(A,row))A[row]++;
if(A[row]<n)
{
if(row == n-1)/
{
ret++;
}
else
{
row++;
A[row] = -1;
}
}
else
row--;
}
return ret;
}
bool check(vector<int> &A,int k)
{
for(int i = 0;i<k;i++)
if(abs(k-i) == abs(A[k] - A[i]) || A[k] == A[i]) return false;
return true;
}
};
class Solution {
public:
int totalNQueens(int n) {
int ret = 0;
vector<int> A(n,0);
solveNQueensCore(ret,A,0);
return ret;
}
void solveNQueensCore(int &ret,vector<int> &A,int row)
{
if(row == A.size())
{
ret ++;
return;
}
for(int i = 0;i<A.size();i++)
{
A[row] = i;
//printf("row = %d,Q= %d\n",row,i);
if(check(A,row))
solveNQueensCore(ret,A,row+1);
}
}
bool check(vector<int> &A,int k)
{
for(int i = 0;i<k;i++)
if(abs(k-i) == abs(A[k] - A[i]) || A[k] == A[i]) return false;
return true;
}
};
class Solution {
public:
vector<vector<string> > solveNQueens(int n) {
vector<vector<string> > ret;
vector<int> A(n,-1);
int row = 0;
while(row >= 0)
{
A[row]++;
//printf("row = %d,Q= %d\n",row,A[row]);
while(A[row]<n && !check(A,row))A[row]++;
//printf("2row = %d,Q= %d\n",row,A[row]);
if(A[row]<n)
{
if(row == n-1)
{
vector<string> tmp(n,string(n,'.'));
for(int i = 0;i<n;i++)
{
tmp[i][A[i]] = 'Q';
//printf("i = %d,Q= %d\n",row,A[i]);
}
//printvecvec(tmp);
ret.push_back(tmp);
}
else
{
row++;
A[row] = -1;
}
}
else
row--;
}
return ret;
}
bool check(vector<int> &A,int k)
{
for(int i = 0;i<k;i++)
if(abs(k-i) == abs(A[k] - A[i]) || A[k] == A[i]) return false;
return true;
}
};
class Solution {
public:
vector<vector<string> > solveNQueens(int n) {
vector<vector<string> > ret;
vector<int> A(n,0);
solveNQueensCore(ret,A,0);
return ret;
}
void solveNQueensCore(vector<vector<string> > &ret,vector<int> &A,int row)
{
if(row == A.size())
{
vector<string> tmp(row,string(row,'.'));
for(int i = 0;i<row;i++)
{
tmp[i][A[i]] = 'Q';
}
//printvecvec(tmp);
ret.push_back(tmp);
return;
}
for(int i = 0;i<A.size();i++)
{
A[row] = i;
//printf("row = %d,Q= %d\n",row,i);
if(check(A,row))
solveNQueensCore(ret,A,row+1);
}
}
bool check(vector<int> &A,int k)
{
for(int i = 0;i<k;i++)
if(abs(k-i) == abs(A[k] - A[i]) || A[k] == A[i]) return false;
return true;
}
};
推荐学习C++的资料
C++标准函数库
在线C++API查询
vector使用方法