代码随想录Day25 回溯算法 LeetCode T51 N皇后问题

简介: 代码随想录Day25 回溯算法 LeetCode T51 N皇后问题

前言

又来到了我们的周末,今天我们挑战一道困难题:N皇后问题,相信大家都玩过一个经典的小游戏:8皇后

游戏规则是:在一个n*n的棋盘上,放置nge 皇后,要求每个皇后所在的一排一列并且对角线都不能存在皇后,放满n个皇后即为胜利.

LeetCode T51 N皇后问题

游戏链接:八皇后游戏 (gitee.io)

题目链接:51. N 皇后 - 力扣(LeetCode)

题目思路:

这题我们仍然使用回溯算法解决问题

首先我们画出树状图,我们以三皇后举例(无解)

回溯三部曲:

1.回溯函数参数

参数我们取一个二维数组(来记录棋盘的情况),一个n来控制我们树的宽度,也就是棋盘的宽度和高度,一个r变量来记录我们此刻位于哪一行

public void backtracking(char[][] chessboard,int n,int r)

2.终止条件

我们发现这道题的取值结果仍然是在叶子结点,所以我们的终止条件就是遍历到最后一行就开始收割结果

if(r == n)
        {
            res.add(Array2List(chessboard));
            return;
        }

3.一次搜索逻辑

for循环,从0开始遍历到n即可,如果判断合法,就填入'Q',再实现回溯即可

这里不用进行去重操作,因为每一排只取一个值

for(int i = 0;i<n;i++)
        {
            if(isVaild(r,i,n,chessboard))
            {
                chessboard[r][i] = 'Q';
                backtracking(chessboard,n,r+1);
                chessboard[r][i] = '.';
            }
        }

4.isValid合法性判断

这里我们需要判断棋盘皇后的落点是否合法,我们只需要比较竖着,和两个对角线是否存在即可,竖着从0遍历到该节点即可,两个对角线别忘记给定边界限制.

public  boolean isVaild(int row,int col,int n,char[][] chessboard )
    {
        //竖着
        for(int i =0;i<row;i++)
        {
            if(chessboard[i][col] == 'Q')
            {
                return false;
            }
        }
        for(int i=row-1,j =col-1;i>=0&&j>=0;i--,j--)
        {
            if(chessboard[i][j] == 'Q')
            {
                return false;
            }
        }
        for(int i=row-1, j=col+1;i>=0&&j<=n-1;i--,j++)
        {
            if(chessboard[i][j] == 'Q')
            {
                return false;
            }
        }
        return true;
    }

5.Array2List

这里细心地小伙伴就会发现我创建的Array2List是自己创建的,因为这里需要进行一次chessboard和list的一次转换,这里我们需要实现list下的这个自定义方法

public List Array2List(char[][] chessboard) {
        List<String> list = new ArrayList<>();
        for (char[] c : chessboard) {
            list.add(String.copyValueOf(c));
        }
        return list;
    }

题目代码:

class Solution {
    List<List<String>> res = new ArrayList<>();
    public List<List<String>> solveNQueens(int n) {
        char chessboard[][] = new char[n][n];
        for(char[] c :chessboard)
        {
            Arrays.fill(c,'.');
        }
        backtracking(chessboard,n,0);
        return res;
    }
    public void backtracking(char[][] chessboard,int n,int r)
    {
        if(r == n)
        {
            res.add(Array2List(chessboard));
            return;
        }
        for(int i = 0;i<n;i++)
        {
            if(isVaild(r,i,n,chessboard))
            {
                chessboard[r][i] = 'Q';
                backtracking(chessboard,n,r+1);
                chessboard[r][i] = '.';
            }
        }
    }
    //定义接口
      public List Array2List(char[][] chessboard) {
        List<String> list = new ArrayList<>();
        for (char[] c : chessboard) {
            list.add(String.copyValueOf(c));
        }
        return list;
    }
    //检查合法性
    public  boolean isVaild(int row,int col,int n,char[][] chessboard )
    {
        //竖着
        for(int i =0;i<row;i++)
        {
            if(chessboard[i][col] == 'Q')
            {
                return false;
            }
        }
        for(int i=row-1,j =col-1;i>=0&&j>=0;i--,j--)
        {
            if(chessboard[i][j] == 'Q')
            {
                return false;
            }
        }
        for(int i=row-1, j=col+1;i>=0&&j<=n-1;i--,j++)
        {
            if(chessboard[i][j] == 'Q')
            {
                return false;
            }
        }
        return true;
    }
}

总结:

本题是我们解决棋盘问题的第一道题目。

如果从来没有接触过N皇后问题的同学看着这样的题会感觉无从下手,可能知道要用回溯法,但也不知道该怎么去搜。

这里我明确给出了棋盘的宽度就是for循环的长度,递归的深度就是棋盘的高度,这样就可以套进回溯法的模板里了

大家可以在仔细体会体会!

相关文章
|
6月前
|
机器学习/深度学习 算法 机器人
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
616 0
|
6月前
|
机器学习/深度学习 算法 C++
【DFS/回溯算法】2016年蓝桥杯真题之路径之谜详解
题目要求根据城堡北墙和西墙箭靶上的箭数,推断骑士从西北角到东南角的唯一路径。每步移动时向正北和正西各射一箭,同一格不重复经过。通过DFS回溯模拟“拔箭”过程,验证路径合法性。已知箭数约束路径唯一,最终按编号输出行走顺序。
|
6月前
|
机器学习/深度学习 算法 机器人
使用哈里斯角Harris和SIFT算法来实现局部特征匹配(Matlab代码实现)
使用哈里斯角Harris和SIFT算法来实现局部特征匹配(Matlab代码实现)
307 8
|
6月前
|
机器学习/深度学习 算法 自动驾驶
基于导向滤波的暗通道去雾算法在灰度与彩色图像可见度复原中的研究(Matlab代码实现)
基于导向滤波的暗通道去雾算法在灰度与彩色图像可见度复原中的研究(Matlab代码实现)
347 8
|
7月前
|
机器学习/深度学习 传感器 算法
【无人车路径跟踪】基于神经网络的数据驱动迭代学习控制(ILC)算法,用于具有未知模型和重复任务的非线性单输入单输出(SISO)离散时间系统的无人车的路径跟踪(Matlab代码实现)
【无人车路径跟踪】基于神经网络的数据驱动迭代学习控制(ILC)算法,用于具有未知模型和重复任务的非线性单输入单输出(SISO)离散时间系统的无人车的路径跟踪(Matlab代码实现)
500 2
|
6月前
|
机器学习/深度学习 数据采集 负载均衡
结合多种启发式解码方法的混合多目标进化算法,用于解决带工人约束的混合流水车间调度问题(Matlab代码实现)
结合多种启发式解码方法的混合多目标进化算法,用于解决带工人约束的混合流水车间调度问题(Matlab代码实现)
318 0
|
6月前
|
机器学习/深度学习 人工智能 算法
【基于TTNRBO优化DBN回归预测】基于瞬态三角牛顿-拉夫逊优化算法(TTNRBO)优化深度信念网络(DBN)数据回归预测研究(Matlab代码实现)
【基于TTNRBO优化DBN回归预测】基于瞬态三角牛顿-拉夫逊优化算法(TTNRBO)优化深度信念网络(DBN)数据回归预测研究(Matlab代码实现)
278 0
|
6月前
|
存储 人工智能 算法
从零掌握贪心算法Java版:LeetCode 10题实战解析(上)
在算法世界里,有一种思想如同生活中的"见好就收"——每次做出当前看来最优的选择,寄希望于通过局部最优达成全局最优。这种思想就是贪心算法,它以其简洁高效的特点,成为解决最优问题的利器。今天我们就来系统学习贪心算法的核心思想,并通过10道LeetCode经典题目实战演练,带你掌握这种"步步为营"的解题思维。
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
404 6
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
486 2

热门文章

最新文章

下一篇
开通oss服务