首页 > 编程语言 >递归与回溯算法

递归与回溯算法

时间:2024-02-23 17:37:13浏览次数:16  
标签:递归 nums 复杂度 算法 vector 回溯

递归

函数中自己调用自己

经典例题:汉诺塔

需要将所有盘子按顺序放到塔C上(问题规模:n) 就需要最大的盘子在C底部 就需要将其余所有盘子移动到塔B上   第二塔上也需要按顺序摆放(问题规模:n-1) 就需要第二大的盘子在B底部 就需要将其余所有盘子移动到另一个塔上 ·································· 这样不断地将问题规模变小(归并排序中的拆分) 当问题被拆到最小时(规模:1),打印出单次步骤即可 递归函数参数含义:将a借助b移动到c,问题规模n

递归思想-自顶向下

1.将一个问题规模变小

2.利用规模化到最小的子问题得出结果

汉诺塔问题规模为1时就可以直接移动

3.用子问题的解得出结果

  可以将递归函数,看成已经实现好的,可以直接用来解决子问题 然后考虑根据子问题的解和当前面对的情况,得出答案     动态规划与递归相反 递归:自顶向下 动态规划:自底向上  

递归函数结构模板

暂时无法在飞书文档外展示此内容 示例:力扣247 中心对称数

递归时间复杂度分析

1.迭代法

计算时间执行函数T(n)

以汉诺塔为例 运行到if分支时,取最大时间复杂度的分支即可 if判断消耗1单位,打印输出消耗1单位 每次调用递归,问题规模-1 所以时间复杂度函数T(n)为 计算极限,去除常数 对递推式迭代展开,找规律 最后推到k=n时,得出时间复杂度O(n) 不便于处理复杂的递归,复杂递归可以借助公式法

2.公式法

额外时间:

例如归并排序中,递归处理完两边数组后,进行合并操作的时间,就是f(n)

递归部分复杂度公式:

三种情况

示例:归并排序时间复杂度:

回溯 Backtracking

尝试 -> 扩展 -> 撤销(回溯)

算法概念

回溯算法是一种试探算法 与暴力搜索的区别: 回溯是一步步向前试探,对每一步探测的情况进行评估,再决定是否深入,可以避免走一些弯路 回溯算法的核心: 出现非法情况时,可以撤销更改,回退到之前的情景 想要采用回溯算法,就必须保证:每次都有多种尝试的可能  

回溯算法程序模板

1.判断当前情况是否非法,若非法直接返回

2.判断递归是否应该结束,若结束,保存当前结果并返回

3.遍历所有可能出现的情况,将其加入尝试容器,并进行递归扩展

4.递归完毕后,立即回溯,取消前一步进行的尝试(将之前尝试的数从尝试容器中踢出)

    示例程序:子集枚举
class Solution {
public:
    vector<int> temp;
    vector<vector<int>> ans;
    void dfs(int cur,vector<int>& nums) //参数:当前位置,原数组
    {
        if(cur == nums.size()) //若已到达数组尽头,停止递归
        {
            ans.push_back(temp); //将临时数组装进答案列表
            return;
        }

        //进行两种可能情况的分支递归
        temp.push_back(nums[cur]); //若当前数为选中状态
        dfs(cur+1,nums);  //此分支下递归,考虑后一个数字是否选中

        temp.pop_back(); //若当前数为不选中状态
        dfs(cur+1,nums);  //此分支下递归,考虑后一个数字是否选中

    }

    vector<vector<int>> subsets(vector<int>& nums) 
    {
        dfs(0,nums);  //从头开始考虑每一个数是否选中
        return ans;
    }
};
 

标签:递归,nums,复杂度,算法,vector,回溯
From: https://www.cnblogs.com/jk-2048/p/18030018

相关文章

  • 贪心算法思想
    贪心算法每一步都找到当前局部最优解,短视,但是有思考贪心算法(GreedyAlogorithm)又叫登山算法,它的根本思想是逐步到达山顶,即逐步获得最优解,是解决最优化问题时的一种简单但是适用范围有限的策略。贪心算法没有固定的框架,算法设计的关键是贪婪策略的选择。每一步都找到最优解,由......
  • 单调栈算法
     定义栈内元素单调按照递增(递减)顺序排列的栈。主要用于找到每一个元素左边或右边,第一个比它大或小的数时,可使用单调栈算法。时间复杂度由于每个元素最多各自进出栈一次,复杂度是O(n)功能递增单调栈:在一个队列中针对每一个元素从它右边找到第一个比它小的元素在一个......
  • 排序算法-归并排序
    时空复杂度时间复杂度:O(nlogn)空间复杂度:O(n)使用了分治思想优势1.稳定归并的时空复杂度非常稳定的,不论是在哪种情况下,归并算法的时间复杂度都不变,2.高效归并算法计算效率相比其他算法也是非常快的 思路图解分把一个有n个元素的数组,分成n个有1个元素的数组然后边比较......
  • [几何算法]任意多边形求面积
    求任意平面多边形的面积通过鞋带定理,在已知多边形各顶点的情况下,可以快速计算出其面积问题分析设一个多边形顶点按逆时针或顺时针顺序为$$P_1(x_1,y_1),P_2(x_2,y_2),\ldots,P_n(x_n,y_n)$$,其中$$P_1=P_{n+1}$$(首尾相连形成闭合多边形)。根据鞋带定理,该多边形的......
  • 基于yolov2深度学习网络的车辆行人检测算法matlab仿真
    1.算法运行效果图预览   2.算法运行软件版本MATLAB2022a 3.算法理论概述      近年来,深度学习在计算机视觉领域取得了显著成果,特别是在目标检测任务中。YOLO(YouOnlyLookOnce)系列算法作为其中的代表,以其高效和实时的性能受到广泛关注。YOLOv2,作为YOL......
  • 基于WIFI指纹的室内定位算法matlab仿真
    1.算法运行效果图预览  2.算法运行软件版本matlab2022a 3.算法理论概述        随着移动互联网和物联网技术的飞速发展,位置服务(LBS)已成为许多应用的核心功能,如导航、社交网络和智能物流等。室外定位技术,如全球定位系统(GPS),已相当成熟并广泛应用。然而,由于建......
  • 类欧几里得算法
    要求类似于这样的东西:\[\begin{align*}f(n,a,b,c)&=\sum\limits_{i=0}^n{\left\lfloor\frac{ai+b}{c}\right\rfloor}\\g(n,a,b,c)&=\sum\limits_{i=0}^n{\left\lfloor\frac{ai+b}{c}\right\rfloor}^2\\h(n,a,b,c)&=\sum\limits_{i=0}^......
  • day41 动态规划part3 代码随想录算法训练营 96. 不同的二叉搜索树
    题目:96.不同的二叉搜索树我的感悟:这题,考的概率不大,听一遍,过一遍就行。理解难点:二叉搜索树定义为什么是累加的听课笔记:代码示例:classSolution:defnumTrees(self,n:int)->int:dp=[0]*(n+1)#创建一个长度为n+1的数组,初始化为0d......
  • day40 动态规划part3 代码随想录算法训练营 343. 整数拆分
    题目:343.整数拆分我的感悟:题目很难,但我动力十足!!理解难点:如何拆分为什么要保留dp[i]听课笔记:代码示例:classSolution:defintegerBreak(self,n:int)->int:#思路:#dp[i]是到目前为止能拆分取的最大值#dp[i]可以拆成j*(集合)......
  • 十大经典排序算法
    十大经典排序算法.md0、算法概述0.1算法分类****十种常见排序算法可以分为两大类:比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序。非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间......