算法系列--递归,回溯,剪枝的综合应用(3)(上)

简介: 算法系列--递归,回溯,剪枝的综合应用(3)(上)

💕"对相爱的人来说,对方的心意,才是最好的房子。"💕

作者:Lvzi

文章主要内容:算法系列–递归,回溯,剪枝的综合应用(3)

大家好,今天为大家带来的是算法系列--递归,回溯,剪枝的综合应用(3),带来几个比较经典的问题N皇后解数独,这两道都是hard级别的题目,但是不要被吓到!请看我的分析

1.N皇后

题目链接:

https://leetcode.cn/problems/n-queens/description/

分析**

1.画决策树

理解题目的意思之后可以开始画决策树,决策树其实也好画,我们只需枚举每一行可能的位置即可,下面是当N = 3时的决策树:

每一层干的事情:

  • 枚举当前行所有的位置,如果可以放皇后,就放,并递归下一行
  • 如果不可以放—剪枝

2.剪枝(本题的难点)

这里先不设计代码,先进行剪枝的操作,分析上图,当我们在某个位置放皇后的时候一定要保证该位置行,列,主对角线,副对角线上没有其他皇后

其实当前行不需要考虑有没有皇后,因为我们是一行一行枚举的,所以只需要考虑列,主对角线,副对角线上没有其他皇后即可

那该怎么判断呢?可能会想到使用3层for循环去遍历与当前位置相关的位置:

  1. 第一层循环遍历当前位置所在列有无皇后
  2. 第二层循环遍历当前位置的主对角线上有无皇后
  3. 第三层循环遍历当前位置副对角线上有无皇后

如果在遍历的过程中发现了皇后,则该皇后会攻击当前要填位置的皇后,所以不能放皇后–剪枝

但是此时的时间复杂度高达3n * 2 ^ n,时间复杂度很高(但是在本题也能通过),其实我们可以采用之前学习过的五子棋中判断当前位置的相关位置有无棋子的策略–使用三个布尔类型的数组

  • boolean[] col:用于标记当前列上有无皇后
  • boolean[] digit1:用于标记当前位置的主对角线上有无皇后
  • boolean[] digit2:用于标记当前位置的副对角线上有无皇后

3.设计代码

全局变量

  • ret:最终的返回值
  • path:记录每次dfs的结果,类型设置为char[][],方便填充
  • 三个布尔类型的数组
  • N:用于表示皇后的个数

dfs

  • 函数头:只需要告诉我当前遍历到哪一行就行–一个参数row
  • 函数体:每一个子问题都是从0开始遍历当前行的所有位置,符合条件的位置添加Q,并递归下一行,不符合条件的位置什么也不干
  • 递归出口:当row==N,即遍历到完所有行后

4.剪枝:

不符合条件的位置直接跳过即可

5.回溯:

回溯只需要将原先填充的位置恢复原状,并将对应位置的三个布尔类型的数组更改为false

代码:

class Solution {
    List<List<String>> ret;// 返回值
    char[][] path;// 记录每次搜索的结果
    boolean[] col;// 列
    boolean[] digit1;// 主对角线
    boolean[] digit2;// 副对角线
    int N;
    public List<List<String>> solveNQueens(int n) {
        N = n;
        ret = new ArrayList<>();
        path = new char[N][N];
        for(int i = 0; i < n; i++)// 预处理  全部填充为. 后续只需要考虑符合条件的情况即可
            Arrays.fill(path[i],'.');
        col = new boolean[N];
        digit1 = new boolean[2 * N];
        digit2 = new boolean[2 * N];
        dfs(0);
        return ret;
    }
    private 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));
            return;
        }
        for(int i = 0; i < N; i++) {
            if(!col[i] && !digit1[i - row + N] && !digit2[i + row]) {
                path[row][i] = 'Q';
                col[i] = digit1[i - row + N] = digit2[i + row] = true;
                dfs(row + 1);// 递归下一行
                path[row][i] = '.';// 回溯
                col[i] = digit1[i - row + N] = digit2[i + row] = false;
            }
        }
    }
}

总结:

  1. path是一个二维的字符数组,path[0]代表一个char[],字符数组就是一个字符串,然后创建一个List类型的集合去依次添加path每一行的元素即可
  2. 将path数组使用Arrays.fill()将path全部填充为.,这样在后面遍历的时候只需要考虑为Q的情况即可
  3. 注意在填充的时候一定要创建新的引用,不要直接添加,因为引用指向的是堆上的地址,你后续的更改会影响集合中存储的内容的
  4. i代表列数,row是行数,明确每一个变量的实际意义

算法系列--递归,回溯,剪枝的综合应用(3)(下)https://developer.aliyun.com/article/1480887?spm=a2c6h.13148508.setting.14.352e4f0emDjgDq

目录
相关文章
|
5天前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习中的优化算法及其应用
本文旨在探讨深度学习中常用的优化算法,包括梯度下降、动量方法、AdaGrad、RMSProp和Adam等。通过分析每种算法的原理、优缺点及适用场景,揭示它们在训练深度神经网络过程中的关键作用。同时,结合具体实例展示这些优化算法在实际应用中的效果,为读者提供选择合适优化算法的参考依据。
|
6天前
|
算法 前端开发 机器人
一文了解分而治之和动态规则算法在前端中的应用
该文章详细介绍了分而治之策略和动态规划算法在前端开发中的应用,并通过具体的例子和LeetCode题目解析来说明这两种算法的特点及使用场景。
一文了解分而治之和动态规则算法在前端中的应用
|
13天前
|
算法 调度
贪心算法基本概念与应用场景
尽管贪心算法在许多问题中都非常有效,但它并不总是会产生最优解。因此,在应用贪心算法前,重要的是先分析问题是否适合采用贪心策略。一些问题可能需要通过动态规划或回溯等其他算法来解决,以找到确切的全局最优解。
44 1
WK
|
15天前
|
机器学习/深度学习 算法 数据挖掘
PSO算法的应用场景有哪些
粒子群优化算法(PSO)因其实现简单、高效灵活,在众多领域广泛应用。其主要场景包括:神经网络训练、工程设计、电力系统经济调度与配电网络重构、数据挖掘中的聚类与分类、控制工程中的参数整定、机器人路径规划、图像处理、生物信息学及物流配送和交通管理等。PSO能处理复杂优化问题,快速找到全局最优解或近似解,展现出强大的应用潜力。
WK
19 1
|
24天前
|
机器学习/深度学习 算法 Python
群智能算法:深入解读人工水母算法:原理、实现与应用
近年来,受自然界生物行为启发的优化算法备受关注。人工水母算法(AJSA)模拟水母在海洋中寻找食物的行为,是一种新颖的优化技术。本文详细解读其原理及实现步骤,并提供代码示例,帮助读者理解这一算法。在多模态、非线性优化问题中,AJSA表现出色,具有广泛应用前景。
|
6天前
|
算法 前端开发
一文了解贪心算法和回溯算法在前端中的应用
该文章深入讲解了贪心算法与回溯算法的原理及其在前端开发中的具体应用,并通过分析LeetCode题目来展示这两种算法的解题思路与实现方法。
|
1天前
|
传感器 算法 C语言
基于无线传感器网络的节点分簇算法matlab仿真
该程序对传感器网络进行分簇,考虑节点能量状态、拓扑位置及孤立节点等因素。相较于LEACH算法,本程序评估网络持续时间、节点死亡趋势及能量消耗。使用MATLAB 2022a版本运行,展示了节点能量管理优化及网络生命周期延长的效果。通过簇头管理和数据融合,实现了能量高效和网络可扩展性。
|
28天前
|
算法 BI Serverless
基于鱼群算法的散热片形状优化matlab仿真
本研究利用浴盆曲线模拟空隙外形,并通过鱼群算法(FSA)优化浴盆曲线参数,以获得最佳孔隙度值及对应的R值。FSA通过模拟鱼群的聚群、避障和觅食行为,实现高效全局搜索。具体步骤包括初始化鱼群、计算适应度值、更新位置及判断终止条件。最终确定散热片的最佳形状参数。仿真结果显示该方法能显著提高优化效率。相关代码使用MATLAB 2022a实现。
|
28天前
|
算法 数据可视化
基于SSA奇异谱分析算法的时间序列趋势线提取matlab仿真
奇异谱分析(SSA)是一种基于奇异值分解(SVD)和轨迹矩阵的非线性、非参数时间序列分析方法,适用于提取趋势、周期性和噪声成分。本项目使用MATLAB 2022a版本实现从强干扰序列中提取趋势线,并通过可视化展示了原时间序列与提取的趋势分量。代码实现了滑动窗口下的奇异值分解和分组重构,适用于非线性和非平稳时间序列分析。此方法在气候变化、金融市场和生物医学信号处理等领域有广泛应用。
|
29天前
|
资源调度 算法
基于迭代扩展卡尔曼滤波算法的倒立摆控制系统matlab仿真
本课题研究基于迭代扩展卡尔曼滤波算法的倒立摆控制系统,并对比UKF、EKF、迭代UKF和迭代EKF的控制效果。倒立摆作为典型的非线性系统,适用于评估不同滤波方法的性能。UKF采用无迹变换逼近非线性函数,避免了EKF中的截断误差;EKF则通过泰勒级数展开近似非线性函数;迭代EKF和迭代UKF通过多次迭代提高状态估计精度。系统使用MATLAB 2022a进行仿真和分析,结果显示UKF和迭代UKF在非线性强的系统中表现更佳,但计算复杂度较高;EKF和迭代EKF则更适合维数较高或计算受限的场景。
下一篇
无影云桌面