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

《算法:递归+记忆化搜索》

递归+记忆化搜索

此文章为简单讲义,详情请移步至主播的主页算法合集:

樱茶喵的个人主页

🔴递归

一.什么是递归?

函数自己调用自己。

二.为什么要用递归?

优点:

  • 代码简洁,可读性好

  • 可用于某些排序算法(归并)和二叉树的遍历,大大简化代码。

不足:

调用函数的开销很大,每次调用都会在栈上为其分配空间,容易栈溢出(Stack Overflow),也就是我们俗称的爆栈。

例:(伪代码)

(1).斐波那契数

void Fib(int n)
{
	if(n == 0 || n == 1)
	return n;
	else
	return Fib(n-2) + Fib(n-1);
}

(2).归并排序

void Merge(int* nums,int left,int right)
{
    if(left >= right)
        return;
    int mid = (left + right)/2;
    Merge(nums,left,mid);
    Merge(nums,mid+1,right);
    合并左右的两个有序数组。
}

(3).二叉树的遍历…

三.怎么理解递归?

本质:

主问题->子问题

子问题->子子问题…

最终将主问题转换为最小子问题,再往上返回。

主问题和子问题、子问题和子问题之间的特点:

都有相同的映射关系f(可以用f来解决所有的子问题)

  • 递归展开的细节图(时间复杂度:O(2^n)
  • 举例说明(斐波那契数)

宏观看待递归的过程:

  1. ​不要太纠结于递归的细节展开图。
  2. 把递归过程想成一个黑盒。
  3. 坚信这个黑盒一定能完成我们赋予他的任务。

四.如何写递归?

1.先找到相同的子问题(函数头)(映射关系)

2.在实现递归过程中只用关心其中一个子问题是如何解决的,因为所有子问题的映射关系是一样的。(函数体的设计)

3.注意递归结束的条件。


🔴记忆化搜索

一.什么是记忆化搜索

记忆化的解释:

就是带备忘录的递归。(容器、数组、哈希表…)

将出现过的子问题的答案存到一个“备忘录”里,之后在调用函数时如果发现该问题已经出现过,则可以在备忘录里找到该问题的答案,直接返回。

二.如何实现记忆化搜索?


1.添加一个备忘录
2.递归每次返回的时候,将结果放到备忘录里面
3.在每次进入递归的时候,往备忘录里面瞅一瞅

斐波那契数举例
class Solution {
public:
    int memo[31];//创建备忘录
    int fib(int n) 
    {
        memset(memo,-1,sizeof memo);//初始化为-1,因为递归过程中的答案不可能为-1
        return dfs(n);
    }
    
    int dfs(int n)
    {
        //"剪枝",判断该子问题是否已出现过,出现则直接返回答案,提升效率最关键的一步
        if(memo[n] != -1)
        return memo[n];

        if(n == 0 || n == 1)
        {
            memo[n] = n;
            return n;
        }

        memo[n] = dfs(n-1)+dfs(n-2);//将子问题答案存到备忘录中
        return memo[n];
    }
};

通过画递归的细节图可以发现,细节图的构成类似于二叉树,查找备忘录的过程就是剪枝的过程。在这一番操作之后,使时间复杂度:从O(2^n)转化为O(n),大大提高了运行效率。

相关文章:

  • 【计算机视觉】OpenCV实战项目- 抖音动态小表情
  • ESP32移植Openharmony外设篇(11) mfrc522射频读卡器
  • 数据处理与机器学习入门
  • MyBatisPlus不等于如何使用
  • qml 中的anchors
  • dfs复习
  • 内核自旋锁
  • 从0到1:Rust 如何用 FFmpeg 和 OpenGL 打造硬核视频特效
  • 如何使用分块策略生成高覆盖率测试用例:需求文档与接口文档的最佳实践
  • 力扣125.验证回文串
  • 标题:Linux系统文件句柄优化全攻略:彻底解决“Too Many Open Files”错误
  • 【算法竞赛】动态规划+记忆化搜索(作物杂交问题)
  • 31天Python入门——第18天:面向对象三大特性·封装继承多态
  • nacos 2.x使用java语言实现自定义Loadbalance
  • 了解可观察性指标:类型、黄金信号和最佳实践
  • SpringBoot框架—classpath、Bean、容器的概念
  • 【Text2reward】code_generation/single_flow/results/gpt-4-0331/maniskill-zeroshot
  • 私有知识库 Coco AI 实战(一):Linux 平台部署
  • LabVIEW 开发中 TCP 与 UDP 协议的差异
  • 《晶振:时空节拍的契约者》
  • 艺术视频手机网站可以做吗/厦门关键词排名seo
  • 北京网站建设降龙/东莞网络推广营销公司
  • 如何查看网站页面大小/seo入门培训学多久
  • 网站中的二级菜单怎么做23/网店推广培训
  • html5做图书馆网站/互联网营销专业
  • 做网站代理/抖音seo排名软件哪个好