[Algorithm][回溯][全排列][子集] + 回溯原理 详细讲解

目录

  • 0.原理讲解
  • 1.全排列
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 2.子集
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现


0.原理讲解

  • 回溯算法通常⽤于解决组合问题、排列问题和搜索问题
  • 回溯算法的基本思想
    • 从⼀个初始状态开始,按照⼀定的规则向前搜索,当搜索到某个状态⽆法前进时,回退到前⼀个状态,再按照其他的规则搜索
    • 回溯算法在搜索过程中维护⼀个状态树,通过遍历状态树来实现对所有可能解的搜索
  • 回溯算法的核⼼思想“试错”
    • 在搜索过程中不断地做出选择,如果选择正确,则继续向前搜索
    • 否则,回退到上⼀个状态,重新做出选择
  • 回溯算法通常⽤于解决具有多个解,且每个解都需要搜索才能找到的问题
  • 总结管他丫的深搜、回溯还是剪枝,画出决策树就完事:P
    • 决策树画的越详细越好
  • 回溯思考流程
    1. 决策树
    2. 设计代码
      • 全局变量
      • DFS()设计
    3. 细节问题:剪枝、回溯、递归出口
  • 注意:没有一成不变的模板,只要能把决策树画出来,把决策树转化成代码就够了

1.全排列

1.题目链接

  • 全排列

2.算法原理详解

  • 全局变量设计
    • vector<vector<int>> ret:存储结果
    • vector<int> path:存储路径
    • vector<bool> check:实现剪枝
  • DFS()设计思路:仅需关心某一个结点在干什么事情即可
  • 细节
    • 回溯
      • 剔除path最后一个元素
      • 修改check数组
    • 递归出口:遇到叶子结点的时候,直接添加结果
      请添加图片描述

3.代码实现

class Solution 
{
    vector<vector<int>> ret;
    vector<int> path;
    vector<bool> check; // 实现剪枝
public:
    vector<vector<int>> permute(vector<int>& nums) 
    {
        check.resize(nums.size(), false);
        DFS(nums);
        return ret;
    }

    void DFS(vector<int>& nums)
    {
        if(nums.size() == path.size())
        {
            ret.push_back(path);
            return;
        }

        for(int i = 0; i < nums.size(); i++)
        {
            if(!check[i])
            {
                path.push_back(nums[i]);
                check[i] = true;
                DFS(nums);

                // 回溯 -> 恢复现场
                path.pop_back();
                check[i] = false;
            }
        }
    }
};

2.子集

1.题目链接

  • 子集

2.算法原理详解

  • 思路一:每次盯着一个数,选或是不选

    • 全局变量
      • vector<int> path
      • vector<vector<int>> ret
    • DFS()设计
      • 函数头void DFS(nums, i)
        • i:下一层递归要选的元素
      • 函数体
        • 选:path += nums[i], DFS(num, i + 1)
        • 不选:DFS(nums, i + 1)
      • 递归出口i == nums.size()
    • 回溯:选时需要回溯
      请添加图片描述
  • 思路二:每次都只选一个数,此后只能选它后面的数

    • 全局变量
      • vector<int> path
      • vector<vector<int>> ret
    • DFS()设计
      • 函数头void DFS(nums, pos)
        • pos:下一层递归选择数时的起始下标
      • 函数体
        • 循环枚举还能选哪些数
      • 递归出口:不需要特定函数出口
    • 回溯:函数返回时回溯
      请添加图片描述
  • 思路二是优于思路一的

    • 思路二每次递归,都会是一个结果,而思路一结果只会出现在叶子节点上
    • 思路二递归的次数是要明显少于思路一的

3.代码实现

// v1.0 每次盯着一个数,选或是不选
class Solution 
{
    vector<vector<int>> ret;
    vector<int> path;
public:
    vector<vector<int>> subsets(vector<int>& nums) 
    {
        DFS(nums, 0);
        return ret;
    }

    void DFS(vector<int>& nums, int i)
    {
        if(i == nums.size())
        {
            ret.push_back(path);
            return;
        }

        // 选
        path.push_back(nums[i]);
        DFS(nums, i + 1);
        path.pop_back(); // 回溯,恢复现场

        // 不选
        DFS(nums, i + 1);
    }
};
----------------------------------------------------------------------------------
// v2.0 每次都只选一个数,此后只能选它后面的数
class Solution 
{
    vector<vector<int>> ret;
    vector<int> path;
public:
    vector<vector<int>> subsets(vector<int>& nums) 
    {
        DFS(nums, 0);
        return ret;
    }

    void DFS(vector<int>& nums, int pos)
    {
        ret.push_back(path);

        for(int i = pos; i < nums.size(); i++)
        {
            path.push_back(nums[i]);
            DFS(nums, i + 1);
            path.pop_back(); // 回溯,恢复现场
        }
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

怎么下载抖音直播视频 怎么解析直播间链接的视频录制保存

尊敬的读者们&#xff0c;你们好&#xff01;今天我们将探讨一个非常实用的技巧——如何下载直播视频。随着网络技术的发展&#xff0c;直播视频已经成为我们日常生活中不可或缺的一部分。无论是观看比赛、欣赏音乐会还是探索新的美食&#xff0c;直播视频都为我们提供了更直观…

【qt】最快的开发界面效率——混合编程

混合编程 一.准备工作1.创建项目2.添加项目资源 二.ui界面设计1.menuBar菜单栏2.action ▲3.toolBar工具栏4.中心组件 三.代码界面设计1.toolBar添加组件2.statusBar状态栏添加组件 四.完成界面的功能1.对action配置信号槽2.对action转到信号槽3.代码添加的组件手动关联槽函数 …

YOLOv8+CLIP实现图文特征匹配

本文通过结合YOLOv8s的高效物体检测能力与CLIP的先进图像-文本匹配技术&#xff0c;展示了深度学习在处理和分析复杂多模态数据中的潜力。这种技术的应用不仅限于学术研究&#xff0c;还能广泛应用于工业、商业和日常技术产品中&#xff0c;以实现更智能的人机交互和信息处理。…

第四届微调——炼丹

学习地址&#xff1a;Tutorial/xtuner/README.md at main InternLM/Tutorial GitHub 笔记 微调是一种在已有的预训练模型基础上&#xff0c;通过使用新的数据对模型进行进一步优化和调整的技术手段。它的目的是使模型能够更好地适应特定的应用场景和任务需求&#xff0c;进一…

IDEA切换分支

方法一 1、选择要切换分支的module 2、右键&#xff0c;选择git 3、再点击branches 4、可以看到当前module的本地分支&#xff08;local Branches&#xff09;及远程分支&#xff08;Remote Branches&#xff09;列表。点击你要切换到的分支,Checkout即可。 方法二 1、点击…

MFC编程之设计美丽的对话框

目录 写在前面&#xff1a; Part 1&#xff1a;美美的设计一下计算器的布局 1.描述文字&#xff1a; ​编辑 2.ID&#xff1a; Part 2&#xff1a;美美熟悉一下计算器的工作流程 Part 3&#xff1a;美美设计一下控件功能 1.edit control&#xff1a; 2.相关变量初始化&…

Copilot for Microsoft 365 扩充新增 16 种语言

最近&#xff0c;微软公司发布公告&#xff0c;进一步扩大 Copilot for Microsoft 365 语言支持&#xff0c;新增 16 种&#xff0c;支持的语言总数达到 25 种。 新支持的语言如下&#xff1a; 阿拉伯语 捷克语 丹麦语 荷兰语 芬兰语 希伯来语 匈牙利语 韩语 挪威语&am…

Java面试之分布式篇

分布式锁的实现方案 &#xff08;1&#xff09;用数据库实现分布式锁比较简单&#xff0c;就是创建一张锁表&#xff0c;数据库对字段作唯一性约束。加锁的时候&#xff0c;在锁表中增加一条记录即可&#xff1b;释放锁的时候删除锁记录就行。如果有并发请求同时提交到数据库&…

二分判定+选插冒排序+归并快速堆希尔+计数排序

二分力扣题 一&#xff1a;搜索二维矩阵 74. 搜索二维矩阵 按照题意&#xff1a;直接利用二维数组转换成一维数组进行求解 方法一&#xff1a;普通等于的二分查找 class Solution { public:bool searchMatrix(vector<vector<int>>& matrix, int target) {t…

Shell编程之循环语甸与函数

for 遍历循环 1&#xff09;for 变量 in 取值列表 for i in $(seq 1 10) do 命令序列 .... done 2&#xff09;for ((变量初始值; 变量范围; 变量的迭代方式)) for ((i1; i<10; i)) do 命令序列 .... done IFS for循环取值列表分隔符 set | grep IFS …

SSH常用功能介绍-高级功能

一、介绍 SSH&#xff08;Secure Shell&#xff09;是一种用于远程登录和执行命令的网络协议&#xff0c;它提供了加密的连接&#xff0c;保证了数据的安全性。除了基本的远程登录功能外&#xff0c;SSH还提供了许多高级功能&#xff0c;以下是一些常用的高级功能介绍&#xf…

Redis集群安装

将Redis安装包分别上传到3个文件夹&#xff0c;并解压缩 #编译并指定安装目录 cd /root/usr/local/redis-cluster/redis-7001/redis-6.2.6/ make make PREFIX/root/usr/local/redis-cluster/redis-7001 install # cd /root/usr/local/redis-cluster/redis-7002/redis-6.2.6/ m…

FreeRTOS二值信号量

目录 一、信号量的概念 1、信号量的基本概念 2、信号量的分类 二、二值信号量简介 三、二值信号量相关API 1、创建二值信号量 2、释放二值信号量 3、获取二值信号量 四、二值信号量实操 1、实验需求 2、CubeMX配置 3、代码实现 一、信号量的概念 1、信号量的基本概…

使用 CloudFlare 后如何才能不影响搜索引擎蜘蛛爬虫

今天,明月给大家再次详细讲解一下,明月在使用 CloudFlare 后如何才能不影响搜索引擎蜘蛛爬虫对站点的抓取,因为这是很多首次使用 CloudFlare 的站长们容易忽略和触犯的问题,并不是 CloudFlare 不友好,而是 CloudFlare 的防火墙(WAF)实在是太给力。其实在【CloudFlare 如…

IDEA及Maven配置代理及Maven中央仓库配置详解

一、配置代理 首先&#xff0c;需要本地开启代理入口&#xff0c;如图。 这个跟你使用代理软件有关。像我使用的是qv2ray。 其次&#xff0c;idea配置代理&#xff0c;如图。 1.1 idea配置代理 打开Settings&#xff0c;如图 1.2 maven配置代理 maven配置代理&#xff0c;修…

2024湖南理工学院程序设计竞赛(同步赛) G. 区间递减(思维题 分类讨论 ST表)

题目 https://ac.nowcoder.com/acm/contest/82672/G 思路来源 出题人 涼風青葉7代码 题解 注意到三种情况即可&#xff0c; 第一种情况&#xff0c;10 9 8 1 2&#xff0c;保留1 第二种情况&#xff0c;6 5 10 9 4 4&#xff0c;保留5 4 4 第三种情况&#xff0c;6 5 4&…

基于Springboot的校园疫情防控管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的校园疫情防控管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系…

Python 整数类型(int)详解:无限范围与多种进制

引言 在编程中&#xff0c;整数是最基本的数据类型之一。不同编程语言对整数的处理方式各不相同&#xff0c;这往往影响到程序的性能和开发者的选择。本文将深入探讨 Python 中的整数类型&#xff08;int&#xff09;&#xff0c;其独特的处理方式&#xff0c;以及它在日常编程…

【数据结构】环状链表OJ题

✨✨✨专栏&#xff1a;数据结构 &#x1f9d1;‍&#x1f393;个人主页&#xff1a;SWsunlight 一、OJ 环形链表&#xff1a; 快慢指针即可解决问题: 2情况&#xff1a; 快指针走到结尾&#xff08;不是环&#xff09;快指针和尾指针相遇&#xff08;是环的&#xff09; …

C语言——文件缓冲区

一、用户缓冲区和系统缓冲区 缓冲区的概念确实可以分为多个层次&#xff0c;其中最常见的两个层次是用户缓冲区和系统缓冲区。 这里的用户缓冲区和系统缓冲区都包括输入输出缓冲区。 1、用户缓冲区&#xff08;User-space Buffer&#xff09; 用户缓冲区是指由用户程序&…