解题思路:
N
皇后问题:把
N
个皇后放值
N*N
的二维矩阵中,保证他们相互不能攻击: 即不在同一行,同一列,同一个斜线上
(
撇捺
)
思想:
DFS +
回溯
从第一行开始放置皇后,每确定一个位置,判断是否会冲突:
是否在同一列,撇,捺, 不可能在同一行, 同一列:纵坐标相同
“
撇
”
,对应的位置,横坐标加上纵坐标的值是相同的。
“
捺
”
,对应的位置,横坐标减去纵坐标的值也是相同的。
当前行位置确定之后, 继续确定下一行的位置
回退,尝试当前行的其它位置
class Solution {
public:
bool isValidPos(vector<pair<int , int>>& curRet , int row , int col)
{
for(const auto& pos : curRet) //判断当前行尝试的皇后位置是否和前面几行的皇后位置有冲突
{
if(pos.second == col //第i个皇后与当前这个点在同一列
|| pos.first + pos.second == row + col //第i个皇后与当前点在撇上,横坐标+纵坐标值相同
|| pos.first - pos.second == row - col) //第i个皇后与当前点在捺上, 横坐标-纵坐标值相同
return false;
}
return true;
}
vector<vector<string>> transResult(vector<vector<pair<int ,int>>>& allRet , int n)
{
vector<vector<string>> allMat;
//所有的方案
for(vector<pair<int ,int>> curRet : allRet)
{
vector<string> curMat(n , string(n , '.'));
//一种方案中的所有皇后位置
for(pair<int ,int> pos : curRet)
{
curMat[pos.first][pos.second] = 'Q';
}
allMat.push_back(curMat);
}
return allMat;
}
void DFS(vector<vector<pair<int , int>>>& allRet , vector<pair<int , int>>& curRet , int curRow ,int n)
{
//如果每一行都没有冲突 , 则是一种可行的方案
if(curRow == n)
{
allRet.push_back(curRet);
return ;
}
//确定当前行的每一个位置是否和已确定的位置有冲突
for(int i = 0 ; i < n; ++i)
{
if(isValidPos(curRet , curRow , i))
{
curRet.push_back(make_pair(curRow , i));
//处理下一行
DFS(allRet , curRet , curRow+1 , n);
//回溯
curRet.pop_back();
}
}
}
vector<vector<string>> solveNQueens(int n)
{
vector<vector<pair<int , int>>> allRet; //按坐标位置存放所有解决方案
vector<pair<int , int>> curRet; //存放一种解决方案中所有皇后的位置
DFS(allRet , curRet , 0 , n);
//把坐标转成string
return transResult(allRet , n);
}
};