N皇后
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
示例:
输入: 4
输出: [
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/n-queens
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题
递归方法,从第一行开始,尝试将棋子放在每一列,下一层递归的条件为数正上方没有棋子,左斜方没有棋子,右斜方没有棋子;
先初始化每一行为n个’.’,放棋子则赋值为Q,逐行操作;
class Solution {
private:
vector<vector<string>> result; //存放结果
vector<string> tmp; //存放每一个结果
public:
vector<vector<string>> solveNQueens(int n) {
string line(n,'.');
NQueens(line,0,n);
return result;
}
private:
void NQueens(string &line,int k, int n) //line的初始化,第k行,一共n行
{
if(n==k)
{
result.push_back(tmp);
return;
}
for(int i=0;i<n;i++)
{
if(Check(k,i,n)){
line[i]='Q'; //单引号
tmp.push_back(line);
line[i]='.';
NQueens(line , k+1, n);
tmp.pop_back();
}
}
}
bool Check(int row, int col, int n)
{
for (int i =0;i<row;i++)
if(tmp[i][col]=='Q')
return false;
for(int i=row-1,j =col-1;i>=0&&j>=0;i--,j-- )
if(tmp[i][j]=='Q')
return false;
for(int i=row-1,j=col+1;i>=0&&j<n;i--,j++)
if(tmp[i][j]=='Q')
return false;
return true;
}
};
注意点
string的用法:
string line(n,'.'); //构造line对象
52. N皇后 II
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回 n 皇后不同的解决方案的数量。
示例:
输入: 4
输出: 2
解释: 4 皇后问题存在如下两个不同的解法。
[
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/n-queens-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题
两题一样,这题是求一共有几种方法,即把上题的保存棋盘改为数量记录+1即可;
依旧需要一个数组保存棋盘,用string数组可以减少维数;
class Solution {
int count=0;
vector<string> pos;
public:
int totalNQueens(int n) {
string line(n,'0');
for(int i=0;i<n;i++)
pos.push_back(line);
NQueen(pos,n,0);
return count;
}
private:
void NQueen(vector<string> &pos,int n, int k) //第k层的位置
{
if(k==n)
{
count++;
return;
}
for(int i=0;i<n;i++)
{
if(Check(i,k,n))
{
pos[k][i]='1';
NQueen(pos,n,k+1);
pos[k][i]='0';
}
}
}
bool Check(int i,int k, int n)
{
for(int t=0;t<k;t++)
if(pos[t][i]=='1')
return false;
for(int m=k-1,j=i-1;m>=0&&j>=0;m--,j--)
if(pos[m][j]=='1')
return false;
for(int m=k-1,j=i+1;m>=0&&j<n;m--,j++)
if(pos[m][j]=='1')
return false;
return true;
}
};
注意点
传入函数的pos需要用引用类型,或者不传入pos进函数,直接在函数内部调用;
void NQueen(int n, int k) //第k层的位置
总结
vector< string >类型很适合放棋盘;
string初始化函数(n,’.’);