LeetCode 51. N皇后【递归、回溯】

难度: 困难

题目描述

n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

LeetCode 51. N皇后【递归、回溯】_第1张图片
上图为 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;
    }
};

你可能感兴趣的:(LeetCode)