N-皇后问题-求解穷举所有解决方案

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

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

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


【示例-1】
在这里插入图片描述

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

示例-2

输入:n = 1
输出:[[“Q”]]


解题思想:
此题,采用回溯法思想求解:

为了判断在当前列和斜线上是否有皇后,定义三个集合,columnsdias1,dias2判断当前列,两条斜线上是否已经有了皇后。

columns的做法很好判断, 使用列的下标就可以代表一个单独的列。
而对于两条斜线,需要分开考虑,观察是否能代表。

这里,我定义dias1为右斜线,并将 row + i作为唯一的标识。可以唯一的标识一个斜线,将其放入set集合中,就可以判断,当前斜线上是否有皇后。
在这里插入图片描述
左上斜也是一样。

[code]

public List<List<String>> solveNQueens(int n) {
        List<List<String>> solutions = new ArrayList<>();
        // 定义索引下标为行 , 值为列
        int[] queue = new int[n];
        Arrays.fill(queue, -1); //  填充
//        存放行和列和每一条斜线所存放的值
        Set<Integer> columns = new HashSet<>();
        // 记录每右下条斜线是否放值
        Set<Integer> dias1 = new HashSet<>();
        // 记录每左上斜是否放值
        Set<Integer> dias2 = new HashSet<>();
//        回溯
        backtracking(solutions, queue, n, 0, columns, dias1, dias2);
        return solutions;
    }
     private void backtracking(List<List<String>> solutions, int[] queue, int n, int row, Set<Integer> columns, Set<Integer> dias1, Set<Integer> dias2) {
            if(row == n){
//              生成结果
                List<String> tmp = generate(queue, n);
                solutions.add(tmp);
            } else{
//                开始尝试在n列中放置
                for(int i = 0; i < n; i ++){
                    // 判断当前填 (row , i )是否符合条件 , columns 代表当前一列中是否有,  dias1,dias2 判断当前斜线是否有 ,
                    if(columns.contains(i) || dias1.contains(row - i) || dias2.contains(row + i) ) continue;
                    queue[row] = i;
                    // 将所有的值进行记录
                    columns.add(i);
                    dias1.add(row - i);
                    dias2.add(row + i);
                    backtracking(solutions, queue, n, row + 1, columns, dias1, dias2);
                    // 回溯后续操作
                    columns.remove(i);
                    dias1.remove(row - i);
                    dias2.remove(row + i);
                }
            }

     }

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


leetcode- N皇后

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值