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

embedded/2024/11/14 21:00:57/

在这里插入图片描述

T04BF

👋专栏: 算法|JAVA|MySQL|C语言

🫵 小比特 大梦想

此篇文章与大家分享递归、搜索与回溯算法关于穷举vs暴搜vs深搜的专题
如果有不足的或者错误的请您指出!

目录

  • 1.全排列
    • 1.1解析
    • 1.2题解
  • 2.子集
    • 2.1解析
      • 2.1.1解法1
      • 2.1.2解法1代码
      • 2.1.3解法2
      • 2.1.4解法2代码

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

🫵 小比特 大梦想

http://www.ppmy.cn/embedded/17687.html

相关文章

大数据集群中部署Hive

hive安装 1&#xff09;把apache-hive-3.1.3-bin.tar.gz上传到Linux的/opt/software目录下 2&#xff09;解压apache-hive-3.1.3-bin.tar.gz到/opt/module/目录下面 tar -zxvf /opt/software/apache-hive-3.1.3-bin.tar.gz -C /opt/module/3&#xff09;修改apache-hive-3.1…

Golang实现一个批量自动化执行树莓派指令的软件(2)指令

简介 基于上篇 Golang实现一个批量自动化执行树莓派指令的软件(1)文本加密&配置&命令行交互实现&#xff0c; 这篇实现的是指令&#xff0c; 即通过ssh执行linux指令的实现。 环境描述 运行环境: Windows&#xff0c; 基于Golang&#xff0c; 暂时没有使用什么不可跨平…

Redis 如何实现分布式锁

课程地址 单机 Redis naive 版 加锁&#xff1a; SETNX ${lockName} ${value} # set if not exist如果不存在则插入成功&#xff0c;返回 1&#xff0c;加锁成功&#xff1b;否则返回 0&#xff0c;加锁失败 解锁&#xff1a; DEL ${lockName}问题1 2 个线程 A、B&#…

Kotlin语法入门-访问和属性修饰符(5)

Kotlin语法入门-访问和属性修饰符(5) 文章目录 Kotlin语法入门-访问和属性修饰符(5)五、访问和属性修饰符1、kotlin修饰符2、internal3、默认修饰符4、open关键字开启继承并实现 五、访问和属性修饰符 1、kotlin修饰符 kotlin在常见的访问修饰符private&#xff0c;protected…

Java -- (part13)

一.异常 1.概述 代码出现了不正常的现象 2.分类 Throwable Error -- 错误 Exception -- 异常 a.编译时期异常:语法没有错误,调用某个方法,直接爆红(因为被调用的方法底层跑了一个编译时期异常) b.运行时期异常:语法没有错误,但是一运行就报错,RuntimeException以及…

CSS 命名规范 - BEM

CSS 命名规范 - BEM 规范化命名 CSS 的选择器按照规范命名的优点&#xff1a; 提高代码的 可读性 和 可维护性提高 可重用性可以有效地避免组件或模块间样式的相互污染&#xff0c;减少嵌套层级 BEM 格式 [prefix]-[block]__[element]--[modifier]Prefix。全局前缀&#x…

C语言例题(递归、二分查找、冒泡排序)

一、递归案例 有5个人坐在在一起&#xff0c;问第5个人多少岁&#xff1f;他说比第4个人大两岁。问第4个人岁数&#xff0c;他说比第3个人大两岁。问第3个人&#xff0c;又说比第2个人大两岁。问第2个人&#xff0c;说比第1个人大2岁。最后问第1个人&#xff0c;他说是10岁。请…

顺序表 (C语言版)

顺序存储&#xff1a; 把逻辑上相邻的元素存储在物理位置上也相邻的存储单元中&#xff0c;元素之间的关系由存储单元的邻接关系来体现。 顺序表的特点&#xff1a; 能在O(1)的时间内找到第i个元素存储密度高拓展容量不方便插入&#xff0c;删除操作不方便 C语言中可使用&am…