N皇后问题

N皇后问题是指在N*N的棋盘上要摆N个皇后,要求任何两个皇后不同行、不同列, 也不在同一条斜线上,给定一个整数n,返回n皇后的摆法有多少种。 n=1,返回1,n=2或3,2皇后和3皇后问题无论怎么摆都不行,返回0,n=8,返回92

N皇后问题解法一,DFS方法。

//给定一个N  返回能找出的有效摆法数
    public static int num(int N) {
        if (N < 1) {
            return 0;
        }
        if (N == 1) {
            return 1;
        }
        //记录列的数组  开辟出N个长度
        int[] record = new int[N];
        int result = process(N, 0, record);
        return result;
    }
    //给定N  当前行  以及记录摆入皇后的列数组(按照深度优先进行遍历,不会出现行重复的情况,所以只需要记录列数组)
    public static int process(int N, int curRow, int[] record) {
        //递归出口
        //当列索引和行索引相等 (满了的时候)停止
        if (N == curRow) {
            return 1;
        }
        int result = 0;
        //循环N次  列索引
        for (int j = 0; j < N; j++) {
            //判断 是否有共列 或者共斜线的情况
            if (isValid(record, curRow, j)) {
                //可以存
                //将对应的列索引值存到当前位置上  即 第0行 存入j=0
                record[curRow] = j;
                //继续找别的皇后 并加入解法中
                result += process(N, curRow + 1, record);
            }
        }
        return result;
    }


    //判断是否有共列 共斜线的情况  只需要看 i - 1 之前的那些行  i及其之后的还没有放入过值
    //参数:当前数组   处理到了第几行  当前列值多少
    public static boolean isValid(int[] record, int curRow, int j) {
        //依次查看每一列的每一个值 是否等于 当前位置(因为存储的时候是将对应的位置索引存入到对应的位置)
        for (int k = 0; k < curRow; k++) {
            //条件一:当前这个K位置上的值是不是等于对应的列索引值
            //例如 处理第2行时, 第一行的0位置上存储的就是0  就代表在第二行的0位置上已经共有共行的数了 不能存
            //条件二:是否是同斜线的  计算方法:如果行-行 == 列-列 就代表是统一条斜线上面的
            //如果当前不是同一条斜线上面的 就缩小范围  k代表了行  record[k]就是列
            if (record[k] == j || Math.abs(curRow - k) == Math.abs(record[k] - j)) {
                //不能存
                return false;
            }
        }
        return true;
    }

解法一耗时较长,可使用位运算加速的方法提升效率。

待实现。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值