(算法)N皇后————<递归>

1. 题⽬链接:51.N皇后

2. 题⽬描述:

3. 解法:

算法思路:

⾸先,我们在第⼀⾏放置第⼀个皇后,然后遍历棋盘的第⼆⾏,在可⾏的位置放置第⼆个皇后,然后 再遍历第三⾏,在可⾏的位置放置第三个皇后,以此类推,直到放置了n个皇后为⽌。

我们需要⽤⼀个数组来记录每⼀⾏放置的皇后的列数。在每⼀⾏中,我们尝试放置⼀个皇后,并检查 是否会和前⾯已经放置的皇后冲突。如果没有冲突,我们就继续递归地放置下⼀⾏的皇后,直到所有 的皇后都放置完毕,然后把这个⽅案记录下来。

在检查皇后是否冲突时,我们可以⽤⼀个数组来记录每⼀列是否已经放置了皇后,并检查当前要放置 的皇后是否会和已经放置的皇后冲突。对于对⻆线,我们可以⽤两个数组来记录从左上⻆到右下⻆的 每⼀条对⻆线上是否已经放置了皇后,以及从右上⻆到左下⻆的每⼀条对⻆线上是否已经放置了皇 后。

• 对于对⻆线是否冲突的判断可以通过以下流程解决:

1. 从左上到右下:相同对⻆线的⾏列之差相同;

2. 从右上到左下:相同对⻆线的⾏列之和相同。

因此,我们需要创建⽤于存储解决⽅案的⼆维字符串数组solutions ,⽤于存储每个皇后的位置的 ⼀维整数数组queens ,以及⽤于记录每⼀列和对⻆线上是否已经有皇后的布尔型数组columns 、 diagonals1 和diagonals2 。 

递归函数设计:void dfs(vector> &solutions, vector &queens, int &n, int  row, vector &columns, vector &diagonals1, vector &diagonals2) 

参数:row(当前需要处理的⾏数);

返回值:⽆;

函数作⽤:在当前⾏放⼊⼀个不发⽣冲突的皇后,查找所有可⾏的⽅案使得放置n个皇后后不发⽣冲 突。  

递归函数流程如下:

1. 结束条件:如果row 等于n ,则表⽰已经找到⼀组解决⽅案,此时将每个皇后的位置存储到字 符串数组board 中,并将board 存储到solutions 数组中,然后返回;

2. 枚举当前⾏的每⼀列,判断该列、两个对⻆线上是否已经有皇后:

        a. 如果有皇后,则继续枚举下⼀列;

        b. 否则,在该位置放置皇后,并将columns 、 diagonals1 和diagonals2 对应的位置 设为true ,表⽰该列和对⻆线上已经有皇后:

                i. 递归调⽤dfs 函数,搜索下⼀⾏的皇后位置。如果该⽅案递归结束,则在回溯时需要将 columns 、 diagonals1 和diagonals2 对应的位置设为false ,然后继续枚举 下⼀列; 

C++算法代码: 

class Solution
{
public:
    vector<vector<string>> answer;   //总答案
    vector<string>key;  //单个选项
    int size;
    int hang[10] = { 0 }, lie[10] = { 0 };   //行列状态数组
    int z_xie[100] = { 0 }, f_xie[100] = { 0 };    //正反斜线状态数组
    void dfs(int t)
    {
        bool temp = false;  //判断一行内是否有合适位置
        //出口
        if (t == size)
        {
            answer.push_back(key);
            return;
        }
        for (int i = 0; i < size; i++)
        {
            //四个方向上都没有皇后,则可以放
            if (!hang[t] && !lie[i] && !z_xie[t - i + size] && !f_xie[t + i])
            {
                temp = true;
                hang[t] = 1, lie[i] = 1;
                z_xie[t - i + size] = 1, f_xie[t + i] = 1;
                key[t][i] = 'Q';
                dfs(t + 1);
                key[t][i] = '.';
                hang[t] = 0, lie[i] = 0;
                z_xie[t - i + size] = 0, f_xie[t + i] = 0;
            }
        }
    }
    vector<vector<string>> solveNQueens(int n)
    {
        size = n;
        //初始化
        string a;
        //开空间
        key.resize(n);
        //初始化
        for(int i=0;i<n;i++)
        {
            key[i].append(n,'.');
        }
        dfs(0);
        return answer;
    }
};

Java算法代码:

class Solution
{
	boolean[] checkCol, checkDig1, checkDig2;
	List<List<String>> ret;
	char[][] path;
	int n;
	public List<List<String>> solveNQueens(int _n)
	{
		n = _n;
		checkCol = new boolean[n];
		checkDig1 = new boolean[n * 2];
		checkDig2 = new boolean[n * 2];
		ret = new ArrayList<>();
		path = new char[n][n];
		for (int i = 0; i < n; i++)
			Arrays.fill(path[i], '.');

		dfs(0);
		return ret;
	}
	public void dfs(int row)
	{
		if (row == n)
		{
			// 添加结果 
			List<String> tmp = new ArrayList<>();
			for (int i = 0; i < n; i++)
			{
				tmp.add(new String(path[i]));
			}
			ret.add(new ArrayList<>(tmp));
		}
		for (int col = 0; col < n; col++)
		{
			// 判断能不能放 
			if (checkCol[col] == false && checkDig1[row - col + n] == false &&
				checkDig2[row + col] == false)
			{
				path[row][col] = 'Q';
				checkCol[col] = checkDig1[row - col + n] = checkDig2[row +
					col] = true;
				dfs(row + 1);
				// 恢复现场 
				path[row][col] = '.';
				checkCol[col] = checkDig1[row - col + n] = checkDig2[row +
					col] = false;
			}
		}
	}
}
  • 12
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

课堂随笔

感谢支持~~~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值