LeetCode 八皇后问题

本文介绍了如何运用回溯法解决LeetCode上的八皇后问题。通过逐行放置皇后并检查冲突,当无法放置时回溯到上一行尝试其他列,详细解释了放置过程及代码实现。
摘要由CSDN通过智能技术生成

题目

n个皇后放在 n ∗ n n*n nn的棋盘上,并且皇后彼此之间不能相互攻击。

分析思路

用穷举法需要尝试 88 =16,777,216 种情况,所以肯定不行

回溯法,第一个应该想到这种方法,需要按照树状进行一层层尝试,如果无法放置,后续的放置都不再考虑,回退到上一步继续。

第一次放置,第一行

列1列2列3列4
×××
××00
×0×0
×00×

第一列标记已放置
column[1]=1
左上到右下标记已放置
left[1-1+4]=left[4]=1
右上到左下标记已放置
right[1+1]=right[2]=1
皇后位置:
queen[1]=1

第二次放置,第二行

列1列2列3列4
×××
×××
××××
×0××

第三列标记已放置
column[3]=1
左上到右下标记已放置
left[2-3+4]=left[3]=1
左上到右下标记已放置
right[2+3]=right[5]=1
皇后位置:
queen[3]=1

第三次放置,第三行

row=3,colum=1, 因为:column[1]=1,所以无法放置
row=3,colum=2, 因为:right[3+2]=right[5]=1,所以无法放置
row=3,colum=3, 因为:column[3]=1,所以无法放置
row=3,colum=4, 因为:left[3-4+4]=left[3]=1,所以无法放置

第4次放置,第三行无法放置,则不再进行

回退到第二行,清空第二行、第三列放置皇后影响的位置。尝试第二行、第四列放置。

代码


package org.example.queen;

public class NQueen {

    //皇后个数
    int n = 4;
    //解个数
    int solveNum = 0;
    //记录皇后左上到右下是否可放置皇后,长度为2*n,这条线上横坐标、纵坐标之差全部相等,y=x+b;
    int[] left = new int[2*n+1];

    //记录皇后右上到左下是否可放置皇后,长度为2*n,这条线上横坐标、纵坐标之和全部相等,y=-x+b;
    int[] right = new int[2*n+1];

    //记录每一列皇后是否可以放置皇后
    int[] column = new int[n+1];

    //记录皇后位置,从第0行开始
    int[] queen = new int[n+1];


    //回归
    public void regression(int row){

        //如果已经有n个皇后,则打印
        if(row == n+1){
            solveNum++;
            System.out.println("解"+solveNum+":");
            for (int i = 1; i <= n ; i++) {
                for (int j = 1; j <= n; j++) {
                    if(queen[i]==j){
                        System.out.print("*"+"\t");
                    }else {
                        System.out.print("0"+"\t");
                    }
                }
                System.out.println();
            }
        }else {
            //循环当前行每一列
            for (int i = 1; i <= n ; i++) {
                //如果当前列可以放皇后,并且当前行、列右上到左下,左上到右下可以放皇后
                if(column[i] == 0 && left[row-i+n] == 0 && right[row+i] == 0){
                    //放置皇后
                    column[i] = 1;
                    left[row-i+n] = 1;
                    right[row+i] = 1;
                    queen[row] = i;
                    //迭代下一行
                    regression(row+1);
                    //回退,当前列放完后,换下一列
                    //已放置的皇后需要清空
                    column[i] = 0;
                    left[row-i+n] = 0;
                    right[row+i] = 0;
                    queen[row] = 0;
                }
                //如果不可以放,则进行下一列,减少程序搜索路径
            }
        }

    }

    public static void main(String[] args) {

        //从第0行开始计算。
        new NQueen().regression(1);

    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值