递归、搜索与回溯算法——穷举vs暴搜vs深搜


T04BF
👋专栏: 算法|JAVA|MySQL|C语言
🫵 小比特 大梦想 此篇文章与大家分享递归、搜索与回溯算法关于穷举vs暴搜vs深搜的专题

如果有不足的或者错误的请您指出!

目录

1.全排列

题目:全排列

1.1解析

假设nums = [1,2,3]

对于这种列举的题,我们的第一步通常是画决策树

如图所示,我们按照要求将决策树显示画出来后,可以发现,实际上就是我们前面讲过的二叉树的遍历

只不过之前的题目已经帮我们把树给画好了,但是这类题目需要我们自己画

按照图,我们发现,实际上对于每一个节点,我们做的事情都是一样的,都是针对三种情况进行讨论,那么我们就可以使用递归来做

此时有几个主要的细节问题

(1)剪枝:如图所示,我们有一些枝干是不用去递归的(图中的红叉叉),就是我们已经讨论过的数字就不能再次讨论的.

我们可以创建一个布尔类型数组,长度与nums数组一样,用于表示当前下标在nums中的值是否已经讨论过

(2)记录:我们用path来记录遍历每一条枝干的节点的值,当path里面值的长度 = nums数组的长度是,我们就将path插入到返回列表中

(3)回溯:我们在递归完某个枝干后,需要将path还原成原来的样子

1.2题解

java 复制代码
class Solution {
    List<List<Integer>> ret;
    List<Integer> path;
    boolean[] check;
    public List<List<Integer>> permute(int[] nums) {
        ret = new ArrayList<>();
        path = new ArrayList<>();
        check = new boolean[nums.length];
        dfs(nums);
        return ret;
    }
    private void dfs(int[] nums) {
        if(path.size() == nums.length) {
            ret.add(new ArrayList(path));
            return;
        }
        for(int i = 0; i < nums.length; i++){
            if(check[i] == false) {
                path.add(nums[i]);
                check[i] = true;
                dfs(nums);

                //回溯
                check[i] = false;
                path.remove(path.size()-1);
            }
        }
    }
}

2.子集

题目:子集

2.1解析

2.1.1解法1

假设数组nums = [1,2,3]

我们直接画决策树

此时我们可以发现,决策树的叶子节点就是我们想要的结果,此时叶子节点也就是递归的出口

而每一个节点做的事情都是一样的,就是选与不选进行分枝

但是此处我们的递归函数还要传一个参数,就是告诉下一次递归选的数是哪个

2.1.2解法1代码

java 复制代码
class Solution {
    private List<List<Integer>> ret = new ArrayList<>();
    private List<Integer> path = new ArrayList<>();
    public List<List<Integer>> subsets(int[] nums) {
        dfs(nums,0);
        return ret;
    }
    private void dfs(int[] nums,int pos) {
        if(pos == nums.length){
            ret.add(new ArrayList(path));
            return;
        }
        path.add(nums[pos]);
        dfs(nums,pos+1);
        path.remove(path.size()-1);
        dfs(nums,pos+1);
    }
}

2.1.3解法2

如图所示的决策图,我们可以以path中元素的个数为标准进行递归,每次递归都从当前传进去的pos开始添加元素,就能保证不重复

此时我们会发现,每一个节点都是我们要的结果,这种解法相对于解法1来说"剪枝"了很多情况

2.1.4解法2代码

java 复制代码
class Solution {
    private List<List<Integer>> ret = new ArrayList<>();
    private List<Integer> path = new ArrayList<>();
    public List<List<Integer>> subsets(int[] nums) {
        dfs(nums,0);
        return ret;
    }
    private void dfs(int[] nums,int pos) {
        ret.add(new ArrayList<>(path));
        for(int i = pos; i < nums.length; i++){
            path.add(nums[i]);
            dfs(nums,i+1);
            path.remove(path.size()-1);
        }
    }
}

感谢您的访问!!期待您的关注!!!


T04BF
🫵 小比特 大梦想

相关推荐
a5876918 分钟前
消息队列(MQ)初级入门:详解RabbitMQ与Kafka
java·分布式·microsoft·面试·kafka·rabbitmq
千里码aicood30 分钟前
【springboot+vue】党员党建活动管理平台(源码+文档+调试+基础修改+答疑)
java·数据库·spring boot
Chan1633 分钟前
【智能协同云图库】基于统一接口架构构建多维度分析功能、结合 ECharts 可视化与权限校验实现用户 / 管理员图库统计、通过 SQL 优化与流式处理提升数据
java·spring boot·后端·sql·spring·intellij-idea·echarts
先做个垃圾出来………39 分钟前
差分数组(Difference Array)
java·数据结构·算法
BillKu1 小时前
Java核心概念详解:JVM、JRE、JDK、Java SE、Java EE (Jakarta EE)
java·jvm·jdk·java ee·jre·java se·jakarta ee
hansang_IR1 小时前
【题解】洛谷 P4286 [SHOI2008] 安全的航线 [递归分治]
c++·数学·算法·dfs·题解·向量·点积
乐迪信息1 小时前
乐迪信息:AI摄像机在智慧煤矿人员安全与行为识别中的技术应用
大数据·人工智能·算法·安全·视觉检测
多恩Stone2 小时前
【3DV 进阶-2】Hunyuan3D2.1 训练代码详细理解下-数据读取流程
人工智能·python·算法·3d·aigc
刘婉晴2 小时前
【Java】NIO 简单介绍
java·nio
渣哥2 小时前
聊聊我和 ArrayList、LinkedList、Vector 的“一地鸡毛”
java