LeetCode--51. N-Queens & 52. N-Queens II

题目链接:https://leetcode.com/problems/n-queens/

N皇后问题,只要理解了八皇后问题就能够抽象出通用的暴力搜索方法(回溯法),参考博客https://blog.csdn.net/To_be_to_thought/article/details/80223682。代码如下:

class Solution {
    
    //8*8的棋盘(没棋子的位置置0)、8条竖线(列上有棋子)、15条正对角线、15条副对角线
	public static char[][] Chess;
	public static boolean[] col_record;
	public static boolean[] main_diag;
	public static boolean[] asso_diag;
    public static int N;
	public static List<List<String>> ret;

    
    //判断棋盘上位置(i,j)是否合法
	public static boolean isOK(int i,int j)
	{
		if(col_record[j] | main_diag[N-1-i+j] | asso_diag[i+j])
			return false;
		return true;
			
	}
    
    
    public List<List<String>> solveNQueens(int n) {
        
        ret=new LinkedList<>();
        Chess=new char[n][n];
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                Chess[i][j]='.';
        col_record=new boolean[n];
        main_diag=new boolean[2*n-1];
        asso_diag=new boolean[2*n-1];
        N=n;
        recursive(0);
        return ret;
    }
    
    public static void recursive(int row)
	{
	//边界条件为当行序数下到8时(0-7)
		if(row>=N)
		{
            LinkedList<String> tmp=new LinkedList<String>();
            for(int i=0;i<N;i++)
                tmp.add(new String(Chess[i]));
			ret.add(tmp);
            return;
		}
		
		for(int col=0;col<N;col++)
		{
			if(isOK(row,col))//如果当前位置合法,则在该位置放置棋子,将相应列、主对角线、副对角线置为“不可放棋子”
			{
				Chess[row][col]='Q';
				col_record[col]=true;
				main_diag[N-1-row+col]=true;
				asso_diag[row+col]=true;
				
				recursive(row+1);//进入下一行的搜索,当前位置的递归结束时要恢复到原状态
				Chess[row][col]='.';
				col_record[col]=false;
				main_diag[N-1-row+col]=false;
				asso_diag[row+col]=false;
			}
		}
	}
}

第二题没啥好说的,跟第一题一模一样。

class Solution {
    
    //8*8的棋盘(没棋子的位置置0)、8条竖线(列上有棋子)、15条正对角线、15条副对角线
	public static char[][] Chess;
	public static boolean[] col_record;
	public static boolean[] main_diag;
	public static boolean[] asso_diag;
    public static int N;
    public static int ret;

    
    //判断棋盘上位置(i,j)是否合法
	public static boolean isOK(int i,int j)
	{
		if(col_record[j] | main_diag[N-1-i+j] | asso_diag[i+j])
			return false;
		return true;
			
	}
    
    
    public static void recursive(int row)
	{
	//边界条件为当行序数下到8时(0-7)
		if(row>=N)
		{
            ret++;
			return;
		}
		
		for(int col=0;col<N;col++)
		{
			if(isOK(row,col))//如果当前位置合法,则在该位置放置棋子,将相应列、主对角线、副对角线置为“不可放棋子”
			{
				Chess[row][col]='Q';
				col_record[col]=true;
				main_diag[N-1-row+col]=true;
				asso_diag[row+col]=true;
				
				recursive(row+1);//进入下一行的搜索,当前位置的递归结束时要恢复到原状态
				Chess[row][col]='.';
				col_record[col]=false;
				main_diag[N-1-row+col]=false;
				asso_diag[row+col]=false;
			}
		}
	}

    public int totalNQueens(int n) {
        Chess=new char[n][n];
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                Chess[i][j]='.';
        col_record=new boolean[n];
        main_diag=new boolean[2*n-1];
        asso_diag=new boolean[2*n-1];
        ret=0;
        N=n;
        recursive(0);
        return ret;
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值