【编程题 】BM59 N皇后问题(详细注释 易懂)

题目描述

题目链接:N皇后问题_牛客题霸_牛客网 (nowcoder.com)

N 皇后问题是指在 n * n 的棋盘上要摆 n 个皇后,
要求:任何两个皇后不同行,不同列也不在同一条斜线上,
求给一个整数 n ,返回 n 皇后的摆法数。

数据范围:   1≤n≤9

要求:空间复杂度  O(1) ,时间复杂度 O(n!)

例如当输入4时,对应的返回值为2,

对应的两种四皇后摆位如下图所示:

示例1

输入:

1

返回值:

1

示例2

输入:

8

返回值:

92

题目解读

N皇后问题,递归里面的经典题目了。从开始学数据结构,我就经常听到这个题目,但是当时水平太菜,根本看不懂这个题的解析,更别说自己做,时隔如此之久,再次遇到,这次我是看了别人的解析,自己做出来的。 但是,不得不说,这个题的难度还是大,加之其他人的解析也有些问题,看着还是挺费劲。

     这个题,就是给一个 n * n 的棋盘, 上面要摆 n 个皇后,也就是一行放一个皇后,但是由于皇后的地位要求,因此要求,任意两个皇后之间,不能在同一行,同一列,也不能在同一条斜线上。如果棋盘的行类 n 较大,人眼去找,也是有点难的,让程序去找,是有点难思考。 而它所要求的,还是找出里面所有的可能性。

解题思想

    题意读懂了,那看看如何做,首先从第一行开始放(以 4*4 的格子为例),先放第一列,第一行第一列肯定和谁都不冲突,然后递归进入第二行,第二行先检查第一列,不行;第二列,不行;第三列,可以; 然后进入第三行第一列,不行;第二列,不行,第三列,不行;第四列,不行;回到上一层递归,画图说明这个过程。

  应该能容易看到,第二行第三列放一个皇后,再加上第一行第一列的皇后,它俩就把第三行放第三个皇后的所有路都堵死了。堪称一夫当关万夫莫开了。 那回退到第二行之后,看第四列,然后再继续往下放,如下图,

 能看得出来,这下是 第四个皇后的生机被完全抹杀了。皇后那是多尊贵的身份,四个主子谁也惹不得,既然第二个皇后怎么放都不行,那就把第一个皇后的位置也给调了。如下图,

   好了,很完美,四位傲娇的皇后,都有她们满意的宫廷了。这就是找到一个可能性的过程,剩下的与上相似,相信你,看完已经懂了。 那就看看代码吧!

代码注释

import java.util.*;


public class Solution {
    /**
     * 
     * @param n int整型 the n
     * @return int整型
     */
    
       // write code here
   // 用来记录排列皇后的可能性
    int possible=0;
    public int Nqueen (int n) {
    /*   用来记录已经放置皇后的位置,用这个数组下标记录皇后所在行,下标对应的值,
         记录皇后所在的列
       */
        int[] pos = new int[n];
       // 进行递归
        recursion(n,0,pos);
        return possible;
        
    }

    public void recursion(int n,int row,int[] pos){
   // 如果当前所在行,已经为n了,表明已经超过放皇后的格子了,也就是n个皇后,
     // 排完了,那就进行计数加 1
        if(row == n){
            possible++;
            return;
        }
        for(int i=0;i<n;i++){
         //  在当前行当前列 放皇后之前,先去检查之前放到皇后的位置 
            if(isValid(pos,row,i)){
           // 如果满足条件,就把当前行当前列计入数组
                pos[row]=i;
                recursion(n,row+1,pos);
            }
                
        }
    }
    public boolean isValid(int[] pos,int row,int col){
       // 查看当前行之前的皇后所在位置,与当前行当前列 有没有同行同列或者同一斜线的
        for(int i=0;i<row;i++ ){
            if( col== pos[i] || Math.abs(row-i)== Math.abs(col-pos[i]))
                return false;
        }
        return true;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值