Problem Description:
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.."]
]
分析:首先我们需要了解在棋盘上放八皇后规则:
1. 行和列都不能有两个以上皇后
2. 对角线不能有两个以上的皇后
然后根据这些规则在棋盘上摆放皇后,如果能把所有皇后都摆上,那么就是有解,否则,无解。
解决问题的关键就是主函数的循环写法,主要思想如下:
1 用一维数组代表棋盘,第i元素代表放置皇后的棋盘行,其值代表填在该行第几列
2. 用i表示填写到第几行了,同时用一个临时数组flag表示从0到i-1已经放置的皇后位置,到第i行放置皇后时依次找到所有可放置的位置,然后利用一个函数判断放置位置是否合法,合法则递归到下一步,直到最后一个皇后放置完毕。
具体代码如下:
class Solution {
public:
bool place(int k, vector<int> &flag)//判断当前皇后放置位置是否合法
{
for(int i=0;i<k;i++)
if(flag[i]==flag[k]||abs(k-i)==abs(flag[k]-flag[i]))
return 0;
return 1;
}
void backtrack(int i, int n, vector<int> &flag, vector<vector<string> > &res)
{
if(i==n)//找到合法的解
{
vector<string> temp;
for(int i=0;i<n;++i)
{
string str;
for(int j=0;j<n;++j)
{
if(j==flag[i])
str+="Q";
else
str+=".";
}
temp.push_back(str);
}
res.push_back(temp);
}
else
for(int j=0;j<n;++j)//寻找第i行所有的可能放置位置
{
flag[i]=j;
if(place(i,flag))
{
backtrack(i+1,n,flag,res);
}
}
}
vector<vector<string> > solveNQueens(int n) {
vector<vector<string> > res;
if(n==0)
return res;
vector<int> flag(n,0);
backtrack(0,n,flag,res);
return res;
}
};