zoukankan      html  css  js  c++  java
  • 力扣No.51 N皇后

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

    上图为 8 皇后问题的一种解法。

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

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

    示例:

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

    皇后彼此不能相互攻击,也就是说:任何两个皇后都不能处于同一条横行、纵行或斜线上。

    ==================================================================================================

    国际象棋中的皇后可以攻击一行、一列和斜线范围内的目标,因此下一行皇后的摆放需要考虑避开上面皇后的攻击范围。最终解法需要每一行都要有一个皇后,可能存在多种解法。这道题可以用回溯的方法来解决,从上往下搜索可能的解法,如果能到达底层则该解法成功,将其放入输出列表。如果发现某一行的某个位置与上面冲突,就往右搜索下一个;如果整行都找不到合适的解,就递归返回上一层再往下搜索。

     代码:

    class Solution {
        public List<List<String>> solveNQueens(int n) {
            char[][] chess = new char[n][n];
            //先将矩阵置'.'
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    chess[i][j] = '.';
                }
            }
            List<List<String>> res = new ArrayList<>();
            dfs(0, chess, res);
            return res;
        }
    
        private void dfs(int row, char[][] chess, List<List<String>> res) {
            //如果能到达底层就加入结果
            if (row == chess.length) {
                res.add(construct(chess));
            }
            //每一行都从左往右搜索
            for (int col = 0; col < chess.length; col++) {
                //判断是否冲突
                if (isValid(chess, row, col)){
                    chess[row][col] = 'Q';
                    dfs(row + 1, chess, res);
                    chess[row][col] = '.';
                }
            }
        }
    
        private boolean isValid(char[][] chess, int row, int col) {
            //判断这一列上面有没有皇后
            for (int i = 0; i < row; i++) {
                if (chess[i][col] == 'Q') {
                    return false;
                }
            }
            //判断此位置右上角有没有皇后
            for (int i = row - 1, j = col + 1; i >= 0 && j < chess.length; i--, j++) {
                if (chess[i][j] == 'Q') {
                    return false;
                }
            }
            //判断此位置左上角有没有皇后
            for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
                if (chess[i][j] == 'Q') {
                    return false;
                }
            }
            return true;
        }
    
        //把将char[][]转换为List<String>
        private List<String> construct(char[][] chess) {
            List<String> path = new ArrayList<>();
            for (int i = 0; i < chess.length; i++) {
                path.add(new String(chess[i]));
            }
            return path;
        }
    }

  • 相关阅读:
    Java对【JSON数据的解析】--Gson解析法
    Java对【JSON数据的解析】--官方解析法
    Java之JSON数据
    网络编程应用:基于UDP协议【实现聊天程序】--练习
    {网络编程}和{多线程}应用:基于UDP协议【实现多发送方发送数据到同一个接收者】--练习
    PHP获取页面执行时间的方法(推荐)
    Linux下查看CPU型号,内存大小,硬盘空间的命令(详解)
    Elasticsearch 全字段搜索_all,query_string查询,不进行分词
    mysql 查询某字段值全是数字
    linux服务器中Apache隐藏index.php失败
  • 原文地址:https://www.cnblogs.com/RS-Sakura/p/13932382.html
Copyright © 2011-2022 走看看