• 力扣算法:N 皇后


    原题链接:https://leetcode-cn.com/problems/n-queens

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

     

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

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

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

    解题思路:

    首先这是经典的皇后问题,所以采用回溯法的方法。我们需要使用三个集合来记录不能放皇后的列或者斜线,所以需要找规律。

    当是左斜线的时候,行下标-列下表 = 定值说明在同一左斜线上

    当是右斜线的时候,行下标+列下表=定值 说明在同一右斜线上

    使用数组 queens 来记录 queens[i]  =p  ,表示第i行的皇后放在下标 p 的位置。

    之后在很剧queens数组来确定list结果。并放入最终的结果集。

    代码如下:

    public List<List<String>> solveNQueens(int n) {
            //结果集
            List<List<String>> result = new ArrayList<List<String>>();
    
            //存放皇后所在的列
            int[] queens = new int[n];
            //三个结果集,分别存储失效的列,左斜线,右斜线
            Set<Integer> lie = new HashSet<Integer>();
            Set<Integer> zuoXie = new HashSet<Integer>(); //行下标-列下表 固定
            Set<Integer> youXie = new HashSet<Integer>();//行下标+列下表 固定
            backtrack(result,queens,n,0,lie,zuoXie,youXie);
    
    
            return result;
        }
    
        public void backtrack(List<List<String>> result,int[] queens,int n,int row,Set<Integer> lie,Set<Integer> zuoXie,Set<Integer> youXie){
            if(row==n){
                //填充完成
                List<String> list=getResult(queens,n);
                result.add(list);
            }else {
                //在第 row 行上,从左到右按顺序排查
                for(int i=0;i<n;i++){
                    //排查列
                    if(lie.contains(i))
                        continue;
                    //排查左斜线
                    if(zuoXie.contains(row-i)){
                        continue;
                    }
                    if (youXie.contains(row+i)) {
                        continue;
                    }
                    //到达这一步说明i点可以存放。
                    queens[row]=i;
                    lie.add(i);
                    zuoXie.add(row-i);
                    youXie.add(row+i);
                    //递归
                    backtrack(result,queens,n,row+1,lie,zuoXie,youXie);
                    //到达这一步说明有问题,需要回溯
                    queens[row]=-1;
                    lie.remove(i);
                    zuoXie.remove(row-i);
                    youXie.remove(row+i);
                }
            }
    
        }
    
        //将queens数组的结果转化为List数组类型
        public List<String> getResult(int[] queens,int n){
            List<String> list = new ArrayList<>() ;
            for (int i=0;i<n;i++){
                char[] rows=new char[n];
                for(int j=0;j<n;j++)
                    rows[j]='.';
                rows[queens[i]]='Q';
                list.add(new String(rows));
            }
            return list;
        }
  • 相关阅读:
    LoadRunner对移动互联网后端服务器压力测试
    Android性能测试工具Emmagee
    Android APP测试流程
    手机APP测试点总结
    Jmeter与LoadRunner的异同
    理解JMeter聚合报告(Aggregate Report)
    树的深度优先遍历和广度优先遍历非递归实现.
    帮助大家理解一下递归函数的返回值...
    使用散列表来降低时间复杂度
    写代码一定要注意边界问题,要考虑全面开始的边界以及结束的边界,已防止出现严重的错误。
  • 原文地址:https://www.cnblogs.com/wys-373/p/13693606.html
Copyright © 2020-2023  润新知