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

news/2025/1/15 17:11:31/

在这里插入图片描述

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/news/1440784.html

相关文章

04.JAVAEE之线程2

1.线程的状态 1.1 观察线程的所有状态 线程的状态是一个枚举类型 Thread.State public class ThreadState {public static void main(String[] args) {for (Thread.State state : Thread.State.values()) {System.out.println(state);}} } NEW:Thread 对象已经有了.start 方…

移动端日志采集与分析最佳实践

前言 做为一名移动端开发者&#xff0c;深刻体会日志采集对工程师来说具有重要意义&#xff0c;遇到问题除了 debug 调试就是看日志了&#xff0c;通过看日志可以帮助我们了解应用程序运行状况、优化用户体验、保障数据安全依据&#xff0c;本文将介绍日志采集的重要性、移动端…

【Java】HOT100 回溯

目录 理论基础 一、组合问题 LeetCode77&#xff1a;组合 LeetCode17&#xff1a;电话号码的字母组合 LeetCode39&#xff1a;组合总和 LeetCode216&#xff1a;组合总和ii LeetCode216&#xff1a;组合总和iii 二、分割问题 LeetCode131&#xff1a;分割回文串 Leet…

牛客NC98 判断t1树中是否有与t2树完全相同的子树【simple 深度优先dfs C++/Java/Go/PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/4eaccec5ee8f4fe8a4309463b807a542 思路 深度优先搜索暴力匹配 思路和算法这是一种最朴素的方法——深度优先搜索枚举 s 中的每一个节点&#xff0c;判断这个点的子树是否和 t 相等。如何判断一个节点的子树是否…

【SpringBoot整合系列】SpringBoot整合JPA

目录 前期回顾ORM解决方案 JPA简介JPA的组成技术ORM映射元数据Java持久化API查询语言&#xff08;JPQL&#xff09; JPA的优势JPA的缺点 Spring Data JPASpring Data JPA简介Spring Data 家族Spring Data JPA、JPA和其他框架之间的关系 SpringBoot整合JPAJPA的核心注解1.依赖2.…

vite-electron 静默打印功能实现

系列文章目录 electronvitevue3 快速入门教程 文章目录 系列文章目录前言一、实现方案二、< webview />讲解1、属性2、 监听事件3、方法 三、 webview与渲染进程通信1.渲染进程--->webview2.webview--->渲染进程&#xff1a; 四、代码实战打印样式说明踩坑说明 前…

如何在Windows 11中安装或删除可选功能?这里提供详细步骤

序言 Windows 11提供了各种各样的功能,其中许多功能,如Linux的Windows子系统(WSL)和语言包,它默认情况下不会安装。你也可以删除默认情况下安装的功能,以下是如何以图形方式或从命令行执行此操作。 关于Windows 11中的可选功能,你需要了解的内容 还有其他添加和删除功…

第一章Hadoop概述

1. Hadoop是什么 Hadoop是一个由Apache基金会所开发的分布式系统基础架构。主要解决&#xff0c;海量数据的存储和海量数据的分析计算问题。广义上来说&#xff0c;Hadoop通常是指一个更广泛的概念--Hadoop生态圈 2. Hadoop发展历史&#xff08;了解&#xff09; Hadoop创始人…