Leetcode 51. N 皇后

Leetcode 51. N 皇后

❤️‍ 来自专栏《LeetCode基础算法题》 欢迎订阅❤️‍

1、题目

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

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

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

实例1

image-20220303215936810

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

实例2

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

提示

1 <= n <= 9

2、思路

首先我们先了解一下什么8皇后问题?

皇后游戏在线玩 点击此处在线玩一把~~~~~

国际象棋中的皇后,可以横向、纵向、斜向移动。如何在一个8X8的棋盘上放置8个皇后,使得任意两个皇后都不在同一条横线、竖线、斜线方向上

说起来有些抽象,我们来看一看递归回溯的详细过程。

king

1.第一层递归,尝试在第一行的第一个位置摆放第一个皇后

2.第二层递归,尝试在第二行摆放第二个皇后(前两格被第一个皇后封锁,只能落在第三格)

3.第三层递归,尝试在第三行摆放第三个皇后(前四格被第一第二个皇后封锁,只能落在第五格

4.第四层递归,尝试在第四行摆放第四个皇后(第一格被第二个皇后封锁,只能落在第二格)

5.第五层递归,尝试在第五行摆放第五个皇后(前三格被前面的皇后封锁,只能落在第四格)

6.由于所有格子都“绿了”,第六行已经没办法摆放皇后,于是进行回溯,重新摆放第五个皇后第八格

7.第六行仍然没有办法摆放皇后,第五行也已经尝试遍了,于是回溯到第四行,重新摆放第四个皇后第七格

8.继续摆放第五个皇后,以此类推…就可以简单理解了

废话少说~~~~~上代码!

3、代码

class Solution {
    
    int array [] = new int [10];
    public List<List<String>> stringList = new ArrayList<List<String>>();
    
    public List<List<String>> solveNQueens(int max) {
        Solution s = new Solution();
        return s.check(0,max);
    }

    public List<List<String>> check(int n, int max){
       if (n == max){//最后一个位置放置了就输出
            stringList.add(to(array, max));
            return stringList;
        }
        for (int i = 0; i < max; i++) {
            array[n] = i;
            if (isExist(n)){//该位置可以放置皇后
                check(n+1,max);//递归到下一个可以放置皇后的位置
            }
         //如果冲突,就继续执行 array[n] = i; 即将第 n 个皇后,放置在本行后移的一个位置上
        }
        return stringList;
    }

    /**
     * 判断该位置是否可行
     * @param n 表示放置第n个皇后
     * @return  boolean 判断该位置是否与之前的放置有冲突
     */
    public boolean isExist(int n){
        //这里循环应该是放置第n个皇后循环判断前n个是否有冲突的情况
        for (int i = 0; i < n; i++) {
            //array[i] == array[n]  判断是否在同一列
            //Math.abs(n-i) == Math.abs(array[n] - array[i]  判断是否在同一斜线上
            //这里肯定很难去理解,举一个例子把这个看成是直角等腰三角形的两条边
            if (array[n] == array[i] || Math.abs(array[n] - array[i]) == Math.abs(n-i)){
                return false;
            }
        }
        return true;
    }
    
    /**
     *  找出每一组满足条件的list集合
     * @param array 找到的皇后位置的整数数组
     * @param max  N皇后
     * @return  一组合理的list集合
     */
    public List<String> to(int array[], int max){
        List<String> list = new ArrayList<>();
        String str = new String();
        StringBuffer sb = new StringBuffer(str);
        for (int i = 0; i < max; i++) {
            sb.delete(0,sb.length());//每次进入循环将字符串重置为空
            for (int j = 0; j < max-1; j++) {
                sb.append(".");//按照题目要求添加点
            }
            sb.replace(array[i], array[i],"Q");
            list.add(sb.toString());
            System.out.println(list);
            System.out.println("i=" + i);
        }
        return list;//传递第list集合
    }
}

4、总结

该题目的最大难度在于回溯。算法可以利用递归实现,也可以利用指针和数组迭代实现。。基于比特位表示的算法,复杂度和一维数组是同一个数量级,只是系数更小,相对快一些。普通的八皇后问题我们一般都是采用一位数组来解决问题。

原题链接:51. N 皇后 - 力扣(LeetCode)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java厂长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值