力扣52. N皇后 II ——递归回溯法求解

在这里插入图片描述

题解:通过递归回溯思想求解,尝试在棋盘上放皇后,判断尝试将皇后在棋盘上是否会冲突,皇后放置完毕则统计结果。 解题思路就是 通过4x4棋盘放置4皇后推广到nxn 放置n 皇后

private static  int count=0;
    public int totalNQueens(int n) {
      
        int[][] board=new int[n][n];			//创建棋盘
          boolean[][] used=new boolean[n][n];	//用于标记棋盘上皇后的存在
        ArrayList<Integer> res=new ArrayList<>();	
        //用于统计结果,在leetCode官方用 static静态变量统计结果会出错
            dfs(board,0,0,used,n,res);	//从棋盘第一个位置开始进行皇后放置
            
            return res.size();
    }
 
      
    static void dfs(int[][]board ,int x ,int y,boolean[][] used,int n, ArrayList<Integer> res){					//x代表行,y代表列
            if (x== board.length){		//如果x超出棋盘说明皇后放置完毕
                int sum =  sumArr(board);	//对皇后统计
                if (sum==n)			 //棋盘上有n个皇后说明找到一种放置结果
                {                                
                   res.add(1);                         
                    }
                return;
            }

            //不放皇后
            if (y<(n-1)){				
     dfs(board,x,y+1,used,n,res);		//列未到最后一列时,尝试下一个位置
            }else{
     dfs(board,x+1,0,used,n,res);  //列到最后一列时,尝试下一行第一个位置  
            }
            //若皇后放置后不受攻击  尝试放
    if (is_Attact(board,x,y,used,n)){// 该位置放置皇后是不会产生攻击
                board[x][y]=1;			//放置
                used[x][y]=true;		//标记该位置已放置

                dfs(board,x+1,0,used,n,res);	//尝试放下一行

            }
            //回溯 恢复状态
            board[x][y]=0;			 
            used[x][y]=false;
        }
        static boolean is_Attact(int[][]board ,int x ,int y,boolean[][] used,int n){  //判断皇后所处位置是否会产生攻击
            for (int j = 0; j < board[0].length;j++) {      //判断行
                if (j==y) continue;					//跳过当前放置的判断
                if (used[x][j]==true)return false;		//皇后攻击
            }
            for (int i = 0; i <board.length ; i++) {        //判断列
                if (i==x) continue;				//跳过当前放置的判断
                if (used[i][y]==true) return false;		//皇后攻击
            }
            int t_x=x;
            int t_y=y;
            for (int i = -(n-1); i <= n-1; i++) {  //判断左下角
  		  if ((x+i)==t_x && (y-i)==t_y)   
    		continue;		//跳过当前放置的判断
      if (x+i>=0 && x+i <=n-1 && y-i>=0 && y-i <=n-1) //确保数组不会越界
                    if (used[x+i][y-i] ==true)
                        return false;				//皇后攻击
            }
            for (int i = -(n-1); i <= n-1; i++) {  //判断右下角
        if ((x+i)==t_x && (y+i)==t_y)   
        	continue;   //跳过当前放置的判断
  if (x+i>=0 && x+i <=n-1 && y+i>=0 && y+i <=n-1)  //确保数组不会越界
                    if (used[x+i][y+i] ==true)
                        return false;				//皇后攻击
            }
            return  true;						//皇后不会攻击
        }
        static int sumArr(int[][] a){
            int s=0;
            for (int i = 0; i < a.length; i++) {
                for (int j = 0; j <a[0].length; j++) {
                    s+=a[i][j];
                }
            }
            return s;
        }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值