侧边栏壁纸
博主头像
GabrielxD

列車は必ず次の駅へ。では舞台は?私たちは?

  • 累计撰写 675 篇文章
  • 累计创建 128 个标签
  • 累计收到 22 条评论

目 录CONTENT

文章目录

【DFS, 回溯】N皇后

GabrielxD
2022-06-08 / 0 评论 / 0 点赞 / 175 阅读 / 691 字
温馨提示:
本文最后更新于 2022-09-27,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

题目

51. N 皇后


按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。

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

给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。

每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q''.' 分别代表了皇后和空位。

示例 1:

image-20220605182549472

输入:n = 4
输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解释:如上图所示,4 皇后问题存在两个不同的解法。

示例 2:

输入:n = 1
输出:[["Q"]]

提示:

  • 1 <= n <= 9

解题

方法一:DFS 回溯

思路

【DFS, 回溯】N皇后 II几乎一样,只不过在每次得到一个合法解后需要生成一个棋盘存入答案数组,而不是仅仅计数,具体解题步骤见【DFS, 回溯】N皇后 II

代码

class Solution {
    private int N;
    private int[] queens;
    private List<List<String>> ans = new ArrayList<>();

    public List<List<String>> solveNQueens(int n) {
        N = n;
        queens = new int[N];
        dfs(0);
        return ans;
    }

    private void dfs(int curr) {
        if (curr == N) {
            ans.add(genBoard());
            return;
        }
        outer: for (int col = 0; col < N; col++) {
            queens[curr] = col;
            for (int row = 0; row < curr; row++) {
                if (queens[curr] == queens[row] ||
                        Math.abs(curr - row) == Math.abs(queens[curr] - queens[row]))
                    continue outer;
            }
            dfs(curr + 1);
        }
    }

    // 生成棋盘
    private List<String> genBoard() {
        List<String> board = new ArrayList<>();
        for (int i = 0; i < N; i++) {
            char[] row = new char[N];
            Arrays.fill(row, '.');
            row[queens[i]] = 'Q';
            board.add(new String(row));
        }
        return board;
    }
}

基于集合的回溯

同[【DFS, 回溯】N皇后 II](【DFS, 回溯】N皇后 II.md),加上生成棋盘并放入答案集合。

class Solution {
    private int n;
    private int[] queens;
    private List<List<String>> ans = new ArrayList<>();
    private Set<Integer> cols = new HashSet<>();
    private Set<Integer> dias1 = new HashSet<>();
    private Set<Integer> dias2 = new HashSet<>();

    public List<List<String>> solveNQueens(int _n) {
        n = _n;
        queens = new int[n];
        Arrays.fill(queens, -1);
        dfs(0);
        return ans;
    }

    private void dfs(int row) {
        if (row == n) {
            ans.add(genBoard());
            return;
        }
        for (int col = 0; col < n; col++) {
            int dia1 = row - col, dia2 = row + col;
            if (cols.contains(col) || dias1.contains(dia1) || dias2.contains(dia2)) continue;
            queens[row] = col;
            cols.add(col);
            dias1.add(dia1);
            dias2.add(dia2);
            dfs(row + 1);
            queens[row] = -1;
            cols.remove(col);
            dias1.remove(dia1);
            dias2.remove(dia2);
        }
    }

    private List<String> genBoard() {
        List<String> board = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            char[] row = new char[n];
            Arrays.fill(row, '.');
            row[queens[i]] = 'Q';
            board.add(new String(row));
        }
        return board;
    }
}
0

评论区