按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
示例 1:

**输入:**n = 4
输出:[[".Q…","…Q",“Q…”,"…Q."],["…Q.",“Q…”,"…Q",".Q…"]]
**解释:**如上图所示,4 皇后问题存在两个不同的解法。
示例 2:
**输入:**n = 1
输出:[[“Q”]]
提示:
1 <= n <= 9
根据题目易得每行每列只能放一个棋子
所以我们可以对每行选定一列后,再看下一行的哪一列能放棋子
此时已经确保了每行一个棋子,我们还需要记录已经有哪些列放置了棋子,在遍历列时剔除
对于斜线,关键是
左上到右下斜线,此时row-column是定值
右上到左下斜线,此时row+column是定值
所以我们可以记录这两个定值,保证row±column不在记录中就可以选定此列。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| class Solution { public: vector<vector<string>> ans; unordered_map<int, bool> flagColumn; unordered_map<int, bool> flag1; unordered_map<int, bool> flag2; vector<vector<string>> solveNQueens(int n) { string mid; for (int i = 0; i < n; i++) { mid.push_back('.'); } vector<string> midRow; traceback(n, 0, mid, midRow); return ans; } void traceback(int n, int row, string &mid, vector<string> &midRow) { if (row == n) { ans.push_back(midRow); return; } for (int i = 0; i < n; i++) { if (flagColumn[i]) continue; int lr = row - i; if (flag1[lr]) continue; int rl = row + i; if (flag2[rl]) continue; flagColumn[i] = true; flag1[lr] = true; flag2[rl] = true;
mid[i] = 'Q'; midRow.push_back(mid); mid[i] = '.'; traceback(n, row + 1, mid, midRow); midRow.pop_back();
flagColumn[i] = false; flag1[lr] = false; flag2[rl] = false; } } };
|