[Algorithm][回溯][组合][目标和][组合总和]详细讲解

目录

  • 1.组合
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 2.目标和
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 3.组合总和
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现


1.组合

1.题目链接

  • 组合

2.算法原理详解

  • 思路:每次都只选一个数,此后只能选它后面的数
  • 函数设计
    • 全局变量
      • vector<vector<int>> ret
      • vector<int> path
    • DFS()设计:void DFS(nums, pos)
    • 递归出口path.size() == k
    • 剪枝:控制参数,每次从此位置下一个位置开始递归
      请添加图片描述

3.代码实现

class Solution 
{int _n;int _k;vector<vector<int>> ret;vector<int> path;
public:vector<vector<int>> combine(int n, int k) {_n = n;_k = k;DFS(1);return ret;}void DFS(int start){if(path.size() == _k){ret.push_back(path);}// 递归 + 剪枝for(int i = start; i <= _n; i++){path.push_back(i);DFS(i + 1);path.pop_back(); // 回溯,恢复现场}}
};

2.目标和

1.题目链接

  • 目标和

2.算法原理详解

  • 本题与子集逻辑几乎相同
  • 本题会实现两种代码,可以通过这两种代码来感受:回溯的两种做法
    • path是全局变量的时候
      • 本题可能会超时
    • path作为参数
      • 此时编译器/代码会代为回溯,每次回溯都省去了一次加/减运算,故效率有所提高
        请添加图片描述

3.代码实现

// v1.0 效率低,可能会超时
class Solution 
{int ret = 0;int path = 0;int _target = 0;
public:int findTargetSumWays(vector<int>& nums, int target) {_target = target;DFS(nums, 0);return ret;}void DFS(vector<int>& nums, int pos){if(pos == nums.size()){if(path == _target){ret++;}return;}// 加path += nums[pos];DFS(nums, pos + 1);path -= nums[pos]; // 回溯,恢复现场// 减path -= nums[pos];DFS(nums, pos + 1);path += nums[pos]; // 回溯,恢复现场}
};
--------------------------------------------------------------------------
// v2.0,效率有所改善
class Solution 
{int ret = 0;int _target = 0;
public:int findTargetSumWays(vector<int>& nums, int target) {_target = target;DFS(nums, 0, 0);return ret;}void DFS(vector<int>& nums, int pos, int path){if(pos == nums.size()){if(path == _target){ret++;}return;}// 加DFS(nums, pos + 1, path + nums[pos]);// 减DFS(nums, pos + 1, path - nums[pos]);}
};

3.组合总和

1.题目链接

  • 组合总和

2.算法原理详解

  • 思路一:每次都只选一个数,此后只能选它及它后面的数

    • 函数设计
      • 全局变量
        • vector<vector<int>> ret
        • vector<int> path
      • DFS()设计:void DFS(nums, pos, sum)
      • 递归出口sum == _target || (sum > _target || pos == nums.size())
      • 回溯:通过sum控制回溯
      • 剪枝:控制pos参数,每次从此位置开始递归
        请添加图片描述
  • 思路二:每次枚举一个数,出现几次

    • 函数设计
      • 全局变量
        • vector<vector<int>> ret
        • vector<int> path
      • DFS()设计:void DFS(nums, pos, sum)
      • 递归出口sum == _target || (sum > _target || pos == nums.size())
      • 回溯:通过sum控制回溯
      • 剪枝:控制pos参数,每次从此位置开始递归
        请添加图片描述

3.代码实现

// v1.0 每次都只选一个数,此后只能选它及它后面的数
class Solution 
{int _target;vector<int> path;vector<vector<int>> ret;
public:vector<vector<int>> combinationSum(vector<int>& nums, int target) {_target = target;DFS(nums, 0, 0);return ret;}void DFS(vector<int>& nums, int pos, int sum){if(sum == _target){ret.push_back(path);return;}if(sum > _target || pos == nums.size()){return;}// 递归决策 + 剪枝for(int i = pos; i < nums.size(); i++){path.push_back(nums[i]);DFS(nums, i, sum + nums[i]);path.pop_back(); // 回溯,恢复现场}}
};
--------------------------------------------------------------------------
// v2.0 每次枚举一个数,出现几次
class Solution 
{int _target;vector<int> path;vector<vector<int>> ret;
public:vector<vector<int>> combinationSum(vector<int>& nums, int target) {_target = target;DFS(nums, 0, 0);return ret;}void DFS(vector<int>& nums, int pos, int sum){if(sum == _target){ret.push_back(path);return;}if(sum > _target || pos == nums.size()){return;}// 枚举个数 + 剪枝for(int i = 0; i * nums[pos] + sum <= _target; i++){if(i){path.push_back(nums[pos]);    }DFS(nums, pos + 1, i * nums[pos] + sum);}// 回溯,恢复现场for(int i = 1; i * nums[pos] + sum <= _target; i++){path.pop_back();}}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/702020.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

金万维动态域名小助手怎么用?

金万维动态域名小助手是一个域名检测工具&#xff0c;使用此工具可以进行检测域名解析是否正确、清除DNS缓存、修改DNS服务器地址及寻找在线客服&#xff08;仅支持付费用户&#xff09;等操作。对不懂网络的用户是一个很好的检测域名的工具&#xff0c;下面我就讲解一下金万维…

【class8】人工智能初步(图像识别-----卷积神经网络)

上节回顾 上节课&#xff0c;我们简单了解了图像识别和深度学习的相关知识。 快速回顾一下吧&#xff5e; A图像识别是以图像的主要特征为基础的。B. 图像分辨率决定图像的质量。 C&#xff0e; 像素是图像中的最小单位D. 在图像识别的原理上&#xff0c;计算机和人类在本质…

VNA校准补充知识点

双端口校准中&#xff0c;SLOT已知直通校准&#xff1b;SLOR未知直通校准&#xff1b;后者精度更高 其余校准方式补充 1.增强型频响校准&#xff08;比SOLT简单&#xff09;&#xff0c;适用于器件的单向测量&#xff08;S11,S21&#xff09; 2.SOLR&#xff08;未知直通校准&…

Java聚合项目打包运行笔记

聚合项目创建 略 聚合项目打包配置 父工程 pom文件添加 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>…

一本书打通SLAM在智能汽车/自动驾驶领域应用

自动驾驶技术已成为当今数字化时代汽车行业的热点话题之一。随着技术的不断成熟&#xff0c;越来越多的车辆采用激光SLAM&#xff08;即时定位与地图构建&#xff09;和视觉SLAM技术&#xff0c;实现更高层次的智能网联汽车。SLAM技术在智能网联汽车中的应用是非常重要的&#…

深入解析Linux逻辑卷管理器(LVM)

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Linux &#xff1a;从菜鸟到飞鸟的逆袭》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、前言 1、Linux的起源与发展 2、什么是逻辑卷管理器&…

Kubernetes学习-深入Pod篇(二) 探针技术详解与应用

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Kubernetes渐进式学习-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 目录 1. 前言 2. 探针是什么 3. 探针的分类 3.1. StartupProbe(启动…

Spring WebFlux 初探-响应式编程-021

&#x1f917; ApiHug {Postman|Swagger|Api...} 快↑ 准√ 省↓ GitHub - apihug/apihug.com: All abou the Apihug apihug.com: 有爱&#xff0c;有温度&#xff0c;有质量&#xff0c;有信任ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplace The Nex…

连接虚拟机的 redis

用Windows 的 Redis Insight 连接虚拟机的 安装redis发现连不上 我的redis是新安装&#xff0c;没有用户名密码&#xff0c;发现是ip问题 127 开头的被我注释了&#xff0c;换成了ifconfig查到的ip

C语言如何删除表中指定位置的结点?

一、问题 如何删除链表中指定位置的结点&#xff1f; 二、解答 删除链表中指定的结点&#xff0c;就像是排好队的⼩朋友⼿牵着⼿&#xff0c;将其中⼀个⼩朋友从队伍中分出来&#xff0c;只需将这个⼩朋友的双⼿从两边松开。 删除结点有两种情况&#xff1a; &#xff08;1&am…

【微信小程序开发(从零到一)【婚礼邀请函】制作】——任务分析和效果实现的前期准备(1)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

【现代C++】三路比较运算符

C20引入了三路比较运算符&#xff08;也称为太空船运算符&#xff0c;<>&#xff09;&#xff0c;它允许同时比较两个值&#xff0c;并返回它们的相对顺序。这个运算符简化了需要定义多个比较运算符&#xff08;如、!、<、<、>、>&#xff09;的类的代码&…