1.题目
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/n-queens
2.解题思路
这道题跪了OrZ。
采用回溯法,一行行尝试皇后的位置,需要判断正左边,右上、左上,正上方是否已经有皇后,当计算变量达到n说明获得一个记过,则记录起来。
3.代码
class Solution {
public:
vector<vector<string>> solveNQueens(int n) {
if (1 == n) return { {"Q"} };
if (n < 4) return {}; //当n为2或3时,不存在符合题意的解
vector<vector<string>> res;
vector<string> v(n, string(n, '.'));
for (int column = 0; column < v.size(); ++column) {
v[0][column] = 'Q';
toSolveNQueens(res, v, 1, 1);
v[0][column] = '.';
}
return res;
}
void toSolveNQueens(vector<vector<string>>& res, vector<string>& v,
int start_row, decltype(v.size()) count) {
//count记录v中已经放置的Q的数量
if (count < v.size())
for (int column = 0; column < v.size(); ++column) {
if (isValid(v, start_row, column)) {
v[start_row][column] = 'Q';
toSolveNQueens(res, v, start_row + 1, count + 1);
v[start_row][column] = '.';//重置为不可行
}
}
else
res.push_back(v);
}
//判断在(row, column)是否可以放置Q,
//思路:只需搜寻点(row,column)之前的部分,来判断点(row, column)是否可以放置Q
bool isValid(vector<string>& v, decltype(v.size()) row, decltype(v.size()) column) {
//点(row, column)左上方向是否有Q
for (auto x = row, y = column; x > 0 && y > 0; --x, --y)
if (v[x - 1][y - 1] == 'Q')
return false;
//点(row, column)右上方向是否有Q
for (auto x = row, y = column + 1; x > 0 && y < v.size(); --x, ++y)
if (v[x - 1][y] == 'Q')
return false;
//点(row, column)正上方向是否有Q
for (auto x = row; x > 0; --x)
if (v[x - 1][column] == 'Q')
return false;
//点(row, column)正左方向是否有Q
for (auto y = column; y > 0; --y)
if (v[row][y - 1] == 'Q')
return false;
return true;
}
};//来自官方题解评论区,id:夜清晨