阿龙的学习笔记---常用算法---递归,回溯法,动态规划,贪心

1. 递归

  • 递归说白了就是程序是自身调用,通常情况下会让复杂的循环变的简单好理解,但由于会涉及到大量的函数调用,时间效率很低,容易造成栈的溢出。剑指说面试题中,在时间要求较低的情况下能用递归的可以用。很容易体现出思路。
  • 数据结构中的是最适合用递归的数据结构。
  • 递归最重要的是设置好递归出口的条件
  • 递归算法的思路是把问题转化为规模缩小了的同类问题的子问题。然后递归调用函数(或过程)来表示问题的解。
  • 典型的递归算法:N!的阶乘,斐波那契数列等。(斐波那契数列使用动态规划更为合适。详解。)

2. 回溯

参考https://blog.csdn.net/zw6161080123/article/details/79985345

  • 回溯法是一种穷举类型的算法,与其说它是一种算法,倒不如说它是一种试法。体现了算法效率与适用性之间的矛盾,二分查找效率很高,但适用性比较低。而穷举法效率最低,但几乎适用于所有问题。

  • 要用回溯法解决问题,那首先要确定问题的状态空间树。看每一步选择有多少个可选值就可以了,第一步有8个可选值,那树第一层就有8个节点,第二步有5个可选值,那第一层每个节点都有5个分支,则第二层有8×5=40个节点,以此类推……到第n层一共有m1×m2×……×mn个节点,其中mi为第i步的可选值的个数。

  • 在n层的状态空间树中,我们要得到一个解向量,每个分量对应每一步选择的结果,显然这个解向量的长度应该为n

  • r代表层数,先从第一层r=0选择一个元素,看看是否满足要求,如果不满于,则取本层下一个元素,满足则r++,进入下一层。然后一直重复这样的操作。

  • 如果到达了r = n-1层,说明到达状态空间树最后一层了,如果符合要求,则找到了一个解向量。如果没有,找本层的下一个。

  • 如果一层中所有元素都找完了,都不符合要求怎么办呢?那就要回溯了。回溯就是返回上一层。如果最后r=0,第一层所有的都不符合,则无解向量。

  • 回溯法解题一般步骤
    (1)针对所给问题,确定问题的解空间:首先应明确定义问题的解空间,问题的解空间应至少包含问题的一个(最优)解。
    (2)确定结点的扩展搜索规则
    (3)以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。

  • 回溯法一般都可以采用递归的方式,解空间找到了则就很好写了;但非递归的效率高,下面详细写一下。

    1: int a[n],i;
    2: 初始化数组a[];
    3: i = 1;
    4: while (i > 0 (有路可走) and (未达到目标))  // 还未回溯到头
    5: {
         
    6:     if(i > n)        // i=n时叶结点符合要求,i变成n+1,说明找到了解向量
    7:     {
            
    8:           搜索到一个解,输出;
    9:     }
    10:     else                                                   // 处理第i个元素
    11:     {
          
    12:           a[i]第一个可能的值;
    13:           while(a[i]在不满足约束条件且在搜索空间内)
    14:           {
         
    15:               a[i]下一个可能的值;
    16:           }
    17:           if(a[i]在搜索空间内)				//剪枝函数,如果到这个情况下不符合题解,则避免无效搜索
    18:          {
         
    19:               标识占用的资源;
    20:               i = i+1;               //扩展下一个结点
    21:          }
    22:          else 
    23:         {
         
    24:               清理所占的状态空间;            // 回溯
    25:               i = i –1; 
    26:          }
    27: }
    
  • 经典的八皇后问题就适合以回溯算法解决:先从第一行第一个开始,找下一行符合的,再找下一行。

    • 回溯递归
    class EightQueen {
         
    private:
    	int array[8];//该数组保表示第i个皇后摆在第i行第array[i]列
    public:
    	void solution(
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值