当前位置: 首页 > ds >正文

【递归、搜索与回溯】专题三 穷举vs暴搜vs回溯vs剪枝

文章目录

  • 1.全排列
    • 1.1 题目
    • 1.2 思路
    • 1.3 代码
  • 2.子集
    • 2.1 题目
    • 2.2 思路
    • 2.3 代码

1.全排列

1.1 题目

题目链接
在这里插入图片描述

1.2 思路

在这里插入图片描述在这里插入图片描述

1.3 代码

class Solution {
public:vector<vector<int>> ret;//最终结果变量vector<int> path;//单次搜索bool check[7];//判断路径上的元素是否已经选择过vector<vector<int>> permute(vector<int>& nums) {dfs(nums);return ret;}void dfs(vector<int>& nums){//如果所有元素都选择过了,就返回,定义函数递归出口if(nums.size() == path.size()){ret.push_back(path);//把此次结果加入到最终结果中return;}//循环遍历nums中的每个元素for(int i = 0; i < nums.size(); i++){if(check[i] == false)//这个数还没加入到path{path.push_back(nums[i]);//把这个数加入到pathcheck[i] = true;//把check坐上true标记,表示已加入到pathdfs(nums);//进行深度优先遍历//dfs完了之后,就相当于进入决策树的下一个分支了//回溯 -> 恢复现场path.pop_back();check[i] = false;}}}
};

2.子集

2.1 题目

题目链接
在这里插入图片描述

2.2 思路

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

2.3 代码

方法一

//方法一 灵神代码
//这段代码实现了一个经典的算法问题:给定一个整数数组 nums,返回其所有可能的子集(幂集)。
//幂集是指一个集合的所有子集组成的集合,包括空集和集合本身。
//代码使用了深度优先搜索(DFS)的方法来生成所有子集。
class Solution {
public:vector<vector<int>> subsets(vector<int>& nums) {vector<vector<int>> ret;//存储返回结果:最终生成的所有子集vector<int> path;//在递归过程中记录当前正在构建的子集int n = nums.size();//nums数组的大小//n:递归过程中用于判断是否已经处理完数组中的所有元素//定义了一个递归函数 dfs,用于深度优先搜索生成所有子集。//auto 表示函数的返回类型会自动推导,这里返回类型为 void。//this auto&& dfs 是一个 C++17 的特性,表示 dfs 是一个可调用对象(可以是函数、lambda 表达式等),并且支持递归调用自身。//int i 是递归函数的参数,表示当前处理到数组 nums 的第 i 个元素。auto dfs = [&](this auto&& dfs, int i) -> void {//递归的终止条件if (i == n) { // 子集构造完毕ret.emplace_back(path);return;}// 选nums[i]path.push_back(nums[i]);dfs(i + 1);path.pop_back(); // 回溯到上一层,需要pop掉push的元素,恢复现场// 不选nums[i]dfs(i + 1); };dfs(0);return ret;}
};
//方法一 代码二 更好理解
class Solution {
public:vector<vector<int>> ret;vector<int> path;vector<vector<int>> subsets(vector<int>& nums) {dfs(nums, 0);return ret;}void dfs(vector<int>& nums, int pos){//递归结束条件if(pos == nums.size()){ret.push_back(path);return;}// 1.选nums[pos]path.push_back(nums[pos]);dfs(nums, pos + 1);path.pop_back();//回溯到上一层时,恢复现场,pop;//2.不选nums[pos]dfs(nums, pos + 1);}
};

方法二

class Solution {
public:vector<vector<int>> ret;vector<int> path;vector<vector<int>> subsets(vector<int>& nums) {dfs(nums, 0);return ret;}void dfs(vector<int>& nums, int pos){ret.push_back(path);//每次进入递归都要先push,每次进入递归都是一个结果for(int i = pos; i < nums.size(); i++){path.push_back(nums[i]);//先加入当前元素dfs(nums, i + 1);//继续往下递归path.pop_back();//恢复现场}}
};
http://www.xdnf.cn/news/12618.html

相关文章:

  • 【Vue】指令补充+样式绑定+计算属性+侦听器
  • 6.6 打卡
  • 西门子 S7-1200 PLC 海外远程运维技术方案
  • vue3+TS+eslint9配置
  • 《强连通分量》题集
  • 如何在Windows本机安装Python并确保与Python.NET兼容
  • day46python打卡
  • 1.4 编译库:静态库、动态库
  • Java并发包中的管程:Lock和Condition
  • 基于STM32语音识别柔光台灯
  • 基于深度学习的无人机轨迹预测
  • 《ERP原理与应用教程》第3版习题和答案
  • VSCode - VSCode 放大与缩小代码
  • 嵌入式开发之STM32学习笔记day22
  • 深入解析:为什么 Redis 比 MySQL 快
  • 如何轻松、安全地管理密码(新手指南)
  • 创客匠人:如何通过精准定位实现创始人IP打造与知识变现
  • [C语言实战]C语言操作MySQL数据库(八)
  • Ubuntu18.6 学习QT问题记录以及虚拟机安装Ubuntu后的设置
  • 下载和安装Visual Studio(开发ASP.NET MVC应用)
  • 华为仓颉语言初识:并发编程之同步机制(上)
  • TensorFlow安装全攻略:快速搭建AI开发环境
  • 图像识别预处理(配合pytesseract使用)
  • 基于最大相邻夹角的边缘点提取(matlab)
  • 华为大规模——重塑生产力
  • 软信天成:数据驱动型背后的人工智能,基于机器学习的数据管理
  • FPGA定点和浮点数学运算-实例对比
  • opencv2/opencv.hpp里面有哪些常用的函数
  • 从混乱到秩序:探索管理系统如何彻底改变工作流程
  • Spring 团队详解:AOT 缓存实践、JSpecify 空指针安全与支持策略升级