n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q'
和 '.'
分别代表了皇后和空位。
示例:
输入: 4 输出: [ [".Q..", // 解法 1 "...Q", "Q...", "..Q."], ["..Q.", // 解法 2 "Q...", "...Q", ".Q.."] ] 解释: 4 皇后问题存在两个不同的解法。
解题思路:回溯法(一定要明白回溯的意思,就是递归的基础上回溯查找解)
解题代码:
1.
class Solution {
private:
vector<vector<string>> res;
vector<bool> col,dia1,dia2;
//尝试在一个n皇后问题中,摆放第i行的皇后问题
void putNQueen(int n, int i, vector<int> &row)
{
if(i==n) //递归终止条件
{
res.push_back(generateBoard(n,row));
return ;
}
for(int j=0;j<n;j++) //递归过程
//尝试将第i行的皇后摆放在第j列
if(!col[j] && !dia1[i+j] && !dia2[i-j+n-1])
{
row.push_back(j);
col[j]=true;
dia1[i+j]=true;
dia2[i-j+n-1]=true;
putNQueen(n,i+1,row);
col[j]=false; //回溯
dia1[i+j]=false;
dia2[i-j+n-1]=false;
row.pop_back();
}
return; //返回
}
vector<string> generateBoard(int n,vector<int> &row)
{
assert(row.size()==n);
vector<string> board(n,string(n,'.'));
for(int i=0;i<n;i++)
board[i][row[i]]='Q';
return board;
}
public:
vector<vector<string>> solveNQueens(int n) {
res.clear();
vector<int> row;
col=vector<bool>(n,false);
dia1=vector<bool>(2*n-1,false);
dia2=vector<bool>(2*n-1,false);
putNQueen(n,0,row);
return res;
}
};