算法系列--递归,回溯,剪枝的综合应用(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

目录
相关文章
|
22小时前
|
机器学习/深度学习 算法
理解并应用机器学习算法:决策树
【5月更文挑战第12天】决策树是直观的分类与回归机器学习算法,通过树状结构模拟决策过程。每个内部节点代表特征属性,分支代表属性取值,叶子节点代表类别。构建过程包括特征选择(如信息增益、基尼指数等)、决策树生成和剪枝(预剪枝和后剪枝)以防止过拟合。广泛应用在信贷风险评估、医疗诊断等领域。理解并掌握决策树有助于解决实际问题。
|
2天前
|
机器学习/深度学习 算法
应用规则学习算法识别有毒的蘑菇
应用规则学习算法识别有毒的蘑菇
|
3天前
|
算法 决策智能 索引
数据结构与算法 回溯
数据结构与算法 回溯
7 1
|
7天前
|
存储 机器学习/深度学习 算法
R语言贝叶斯Metropolis-Hastings采样 MCMC算法理解和应用可视化案例
R语言贝叶斯Metropolis-Hastings采样 MCMC算法理解和应用可视化案例
|
7天前
|
数据采集 机器学习/深度学习 算法
数据分享|WEKA关联规则挖掘Apriori算法在学生就业数据中的应用
数据分享|WEKA关联规则挖掘Apriori算法在学生就业数据中的应用
|
11天前
|
机器学习/深度学习 自然语言处理 算法
机器学习算法原理与应用:深入探索与实战
【5月更文挑战第2天】本文深入探讨机器学习算法原理,包括监督学习(如线性回归、SVM、神经网络)、非监督学习(聚类、PCA)和强化学习。通过案例展示了机器学习在图像识别(CNN)、自然语言处理(RNN/LSTM)和推荐系统(协同过滤)的应用。随着技术发展,机器学习正广泛影响各领域,但也带来隐私和算法偏见问题,需关注解决。
|
12天前
|
机器学习/深度学习 算法 C语言
【C言专栏】递归算法在 C 语言中的应用
【4月更文挑战第30天】本文介绍了递归算法在C语言中的应用,包括基本概念(通过调用自身解决子问题)、特点(调用自身、终止条件、栈空间)和实现步骤(定义递归函数、分解问题、设置终止条件、组合解)。文中通过阶乘计算和斐波那契数列两个案例展示了递归的使用,强调了递归可能导致的栈溢出问题及优化需求。学习递归有助于理解和应用“分而治之”策略。
|
2天前
|
算法 数据安全/隐私保护 计算机视觉
基于二维CS-SCHT变换和LABS方法的水印嵌入和提取算法matlab仿真
该内容包括一个算法的运行展示和详细步骤,使用了MATLAB2022a。算法涉及水印嵌入和提取,利用LAB色彩空间可能用于隐藏水印。水印通过二维CS-SCHT变换、低频系数处理和特定解码策略来提取。代码段展示了水印置乱、图像处理(如噪声、旋转、剪切等攻击)以及水印的逆置乱和提取过程。最后,计算并保存了比特率,用于评估水印的稳健性。
|
3天前
|
存储 算法 数据可视化
基于harris角点和RANSAC算法的图像拼接matlab仿真
本文介绍了使用MATLAB2022a进行图像拼接的流程,涉及Harris角点检测和RANSAC算法。Harris角点检测寻找图像中局部曲率变化显著的点,RANSAC则用于排除噪声和异常点,找到最佳匹配。核心程序包括自定义的Harris角点计算函数,RANSAC参数设置,以及匹配点的可视化和仿射变换矩阵计算,最终生成全景图像。
|
3天前
|
算法 Serverless
m基于遗传优化的LDPC码NMS译码算法最优归一化参数计算和误码率matlab仿真
MATLAB 2022a仿真实现了遗传优化的归一化最小和(NMS)译码算法,应用于低密度奇偶校验(LDPC)码。结果显示了遗传优化的迭代过程和误码率对比。遗传算法通过选择、交叉和变异操作寻找最佳归一化因子,以提升NMS译码性能。核心程序包括迭代优化、目标函数计算及性能绘图。最终,展示了SNR与误码率的关系,并保存了关键数据。
12 1