leetcode n皇后问题

题目描述:

在8x8格的国际象棋上摆放八个皇后,使其不能互相攻击:任意两个皇后都不能处于同一行、同一列、同一斜线上请问有多少种摆法?

废话不多说直接上代码

package com.ncst2.traceback;

/**
 * @Date 2020/11/1 22:36
 * @Author by LSY
 * @Description N 皇后问题 ,优化
 */
public class NQueen2 {

    /**
     * 存一个皇后的列号(在第几列)
     */
    private int[] queens;

    /**
     * 存放每一列是否有皇后
     */
    private boolean[] cols;

    /**
     * 从左上 到 右下的斜线,标记着某一对角线是否有皇后
     */
    private boolean[] leftTop;

    /**
     * 从右上 到 左下的斜线,标记着某一对角线是否有皇后
     */
    private boolean[] rightTop;

    /**
     * 存放有多少种方式
     */
    private int ways;

    public static void main(String[] args) {
        new NQueen2().placeQueen(4);

    }

    public void placeQueen(int n) {
        if (n < 1) {
            return;
        }
        queens = new int[n];
        cols = new boolean[n];
        leftTop = new boolean[(n << 1) - 1];
        rightTop = new boolean[leftTop.length];
        place(0);
        System.out.println("ways = " + ways);
    }

    /**
     * 从第row 行开始摆放 皇后
     */
    private void place(int row) {
        if (row == cols.length) {
            ways++;
            show();
            return;
        }
        for (int col = 0; col < cols.length; col++) {
            int leftIdx = row - col + cols.length - 1;
            int rightIdx = row + col;

            if (cols[col]) {
                continue;
            }
            if (leftTop[leftIdx]) {
                continue;
            }
            if (rightTop[rightIdx]) {
                continue;
            }
            //剪枝 + 存储第cols[col] 存在皇后
            cols[col] = leftTop[leftIdx] = rightTop[rightIdx] = true;
            //递归
            place(row + 1);
            //回溯 将 cols[col] 的皇后去除掉,将斜线重新置为 false
            cols[col] = leftTop[leftIdx] = rightTop[rightIdx] = false;
        }
    }

    /**
     * 打印每一次皇后的分布图
     */
    private void show() {
        for (int row = 0; row < queens.length; row++) {
            for (int col = 0; col < queens.length; col++) {
                if (queens[row] == col) {
                    System.out.print("1 ");
                } else {
                    System.out.print("0 ");
                }
            }
            System.out.println();
        }
        System.out.println("===============");
    }
}

运行结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值