美文网首页
N皇后问题

N皇后问题

作者: Gyu2233 | 来源:发表于2020-10-17 15:57 被阅读0次

    转载请注明出处:https://www.jianshu.com/u/b03dcb8185b5

    题目链接
    题目:n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。(输入输出:给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。)

    8皇后的一种解法

    输入输出实例:
    input:4
    output:
    [
    [".Q..", // 解法 1
    "...Q",
    "Q...",
    "..Q."],
    ["..Q.", // 解法 2
    "Q...",
    "...Q",
    ".Q.."]
    ]

    代码排版这么优美,注释如此详细,还有啥看不懂,欢迎评论区讨论

    //参考代码如下
    class Solution {
        private int n;
        private boolean[] col;//记录某一列是否放置了皇后
        private boolean[] main;//记录主对角线上的某一格是否放置了皇后
        private boolean[] sub;//记录副对角线上的某一格是否放置了皇后
        private List<List<String>> res;
        
        public List<List<String>> solveNQueens(int n) {
            res = new ArrayList<>();
            if(n == 0){
                return res;
            }
            //设置成员变量,减少参数传递
            this.n = n;
            this.col = new boolean[n];
            this.main = new boolean[2*n-1];
            this.sub = new boolean[2*n-1];
            Deque<Integer> path = new ArrayDeque<>();
            dfs(0, path);
            return res;
        }
    
        public void dfs(int row, Deque<Integer> path){
            if(row == n){
                //深搜到下标为n,表示[0,n-1]已经填完了,得到一个结果
                List<String> graph = convertGraph(path);
                res.add(graph);
                return;
            }
            //对于下标为row的每一列,尝试是否可以放置
            for(int i = 0; i < n; i++){
                if(!col[i] && !main[row+i] && !sub[row-i+n-1]){
                    path.addLast(i);
                    col[i] = true;
                    main[row+i] = true;
                    sub[row-i+n-1] = true;
    
                    dfs(row+1, path);
    
                    //递归完成后,回到之前的起点,需要将递归之前的操作恢复
                    col[i] = false;
                    main[row+i] = false;
                    sub[row-i+n-1] = false;
                    path.removeLast();
                }
            }
        }
    
        public List<String> convertGraph(Deque<Integer> path){
            List<String> graph = new ArrayList<>();
            for(Integer i : path){
                StringBuilder row = new StringBuilder();
                row.append(".".repeat(n));
                row.replace(i, i+1, "Q");
                graph.add(row.toString());
            }
            return graph;
        }
    }
    

    再来一道相似题


    题目链接
    题目:n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。(给定一个整数 n,返回 n 皇后不同的解决方案的数量。)

    与上面一题的区别在于不记录每一种具体情况

    输入输出示例:
    input: 4
    output: 2
    解释: 4 皇后问题存在如下两个不同的解法。
    [
    [".Q..", // 解法 1
    "...Q",
    "Q...",
    "..Q."],
    ["..Q.", // 解法 2
    "Q...",
    "...Q",
    ".Q.."]
    ]

    //参考代码如下
    class Solution {
    
        private boolean col[];
        private boolean main[];
        private boolean sub[];
    
        public int totalNQueens(int n) {
            col = new boolean [n];
            main = new boolean [2*n - 1];
            sub = new boolean [2*n - 1];
            return getResult(n, 0);
        }
    
        private int getResult(int n, int row){
            int res = 0;
            if(row == n){
                return 1;
            }
    
            for(int i = 0; i < n; i++){
                if(!col[i] && !main[row+i] && !sub[row-i+n-1]){
                    //path.addLast(i);
                    col[i] = true;
                    main[row+i] = true;
                    sub[row-i+n-1] = true;
    
                    res += getResult(n, row+1);
    
                    //递归完成后,回到之前的起点,需要将递归之前的操作恢复
                    col[i] = false;
                    main[row+i] = false;
                    sub[row-i+n-1] = false;
                    //path.removeLast();
                }
            }
    
            return res;
        }
    }
    

    相关文章

      网友评论

          本文标题:N皇后问题

          本文链接:https://www.haomeiwen.com/subject/pzffmktx.html