LeetCode 51. N皇后【递归、回溯】
难度: 困难
题目描述
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 Q 和 . 分别代表了皇后和空位。
示例:
输入: 4 输出: [ [".Q..", // 解法 1 "...Q", "Q...", "..Q."], ["..Q.", // 解法 2 "Q...", "...Q", ".Q.."] ] 解释: 4 皇后问题存在两个不同的解法。
思路
皇后需要满足每行每列只有一个,那么皇后的位置一定是n的一个全排列。皇后们还需要在对角线上不冲突,这就需要检测了,所以可以先生成全排列,再在生成全排列的过程中检测对角线上是否发生冲突。
代码
class Solution { public: vector<vector<string>> solveNQueens(int n) { bool used[n + 1] = { }; // 第i行是否有皇后 int permutation[n + 1] = { }; // 当前排列(第i列皇后在第permutation[i]行上) vector<vector<string>> ans; vector<string> blank(n, string(n, .)); function<void(int, int)> n_queens; n_queens = [&used, &permutation, &n_queens, &blank, &ans](int n, int index) { if (index == n + 1) { // 找到一个合法方案 auto res = blank; for (int i = 1; i <= n; ++i) res[permutation[i] - 1][i - 1] = Q; ans.push_back(res); } for (int x = 1; x <= n; ++x) { // 第x行 if (not used[x]) { bool flag = true; // 表示当前皇后不会和之前皇后冲突 for (int pre = 1; pre < index; ++pre) { if (abs(index - pre) == abs(x - permutation[pre])) { // 与之前的皇后在一条对角线上 flag = false; break; } } if (flag) { permutation[index] = x; used[x] = true; n_queens(n, index + 1); used[x] = false; } } } }; n_queens(n, 1); return ans; } };
上一篇:
IDEA上Java项目控制台中文乱码