在LeetCode中有N皇后问题,其中有让求n皇后解决方案的个数,也有让求n皇后解决方案的棋盘展示。其实二者的算法是一样的,只是中间的处理过程不一样。下面我就这两道题写下我的思路。
N皇后
题解:
首先遇到N皇后问题,首先要想到用回溯法。递归的层数是N,每一层递归就解决每一行的皇后放在哪。所以我们要每一层递归中用一个循环,来看把皇后放在那一列合适(没有皇后攻击),然后就把皇后放在该位置,然后进行下一层递归。递归完后,撤销放置在该地方的皇后(回溯),查找下一个可能的位置。
代码:
/*
* @lc app=leetcode.cn id=51 lang=cpp
*
* [51] N 皇后
*/
// @lc code=start
class Solution {
public:
vector<string> ve;
vector<vector<string>> res;
bool attack(int x,int y,int n){//判断是否能攻击到,返回true为是
int i,j;
for(i=x-1;i>=0;i--){//检查上面
if(ve[i][y]=='Q') return true;
}
i=x-1,j=y-1;
while(i>=0&&j>=0){//检查左上
if(ve[i][j]=='Q') return true;
i--;
j--;
}
i=x-1,j=y+1;
while(i>=0&&j<n){//检查右上
if(ve[i][j]=='Q') return true;
i--;
j++;
}
return false;
}
void help(int n,int index){
if(index==n){
res.push_back(ve);
return ;
}
int j;
for(j=0;j<n;j++){
if(!attack(index,j,n)){ //放在此处不会受到攻击
ve[index][j]='Q'; //放下
help(n,index+1); //递归,找下一层的解
ve[index][j]='.'; //回溯
}
}
}
vector<vector<string>> solveNQueens(int n) {
ve.resize(n);
for(int i=0;i<n;i++) ve[i].resize(n,'.');
help(n,0);
return res;
}
};
// @lc code=end
N皇后二(求个数)
题解
如上
代码
class Solution {
public:
int ve[9][9]={0};
int res=0;
bool attack(int x,int y,int n){//判断是否能攻击到,返回true为是
int i,j;
for(i=x-1;i>=0;i--){//检查上面
if(ve[i][y]==1) return true;
}
i=x-1,j=y-1;
while(i>=0&&j>=0){//检查左上
if(ve[i][j]==1) return true;
i--;
j--;
}
i=x-1,j=y+1;
while(i>=0&&j<n){//检查右上
if(ve[i][j]==1) return true;
i--;
j++;
}
return false;
}
void help(int n,int index){
if(index==n){
res++;
return ;
}
int j;
for(j=0;j<n;j++){
if(!attack(index,j,n)){
ve[index][j]=1;
help(n,index+1);
ve[index][j]=0;
}
}
}
int totalNQueens(int n) {
help(n,0);
return res;
}
};