递归练习八(记忆化搜索)

一、解题心得

记忆化搜索就是带着备忘录递归搜索。

函数体设计:进 dfs 后先看看要找的值是不是在备忘录里面存着,有就直接返回,没有再考虑递归出口和中间函数逻辑。

记忆化搜索和递归暴搜都没有很大的关系,而是和动态规划问题有很大联系。

之前递归的暴搜问题基本都是用中间值 tmp 来记录每一条路径过程中的值,然后从上往下到出口时更新一次答案。

但是记忆化搜索是根据之前递归出的值来更新这次递归的值,防止一个值重复计算导致超时。这个思路不就是动态规划问题中把值记录在 dp 表中,用前面的值更新后面的值。

所以记忆化搜索不可避免的一定会有返回值,这也是不同于暴搜的,因为暴搜的值会存在 tmp 不用刻意返回。

所以一定要注意思考记忆化搜索的问题一定一定不是从暴搜角度考虑,而是从动态规划问题考虑。二者是明显不同的代码和思考逻辑!!!!!!!

下面是同一道题的暴搜(超时)和记忆化搜索(思考逻辑类似dp)的代码对比:

329. 矩阵中的最长递增路径 - 力扣(LeetCode)

1、暴搜:

class Solution {
public:
    int ans = 0;
    int tmp = 0;
    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
    bool vis[201][201];
    int m, n;
    int longestIncreasingPath(vector<vector<int>>& matrix) {
        m = matrix.size();
        n = matrix[0].size();
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                vis[i][j] = true;
                tmp++;
                dfs(i, j, matrix);
                vis[i][j] = false;
                tmp--;
            }
        }
        return ans;
    }
    void dfs(int x, int y, vector<vector<int>>& matrix)
    {
        ans = max(ans, tmp);
        for(int i = 0; i < 4; i++)
        {
            int a = x + dx[i];
            int b = y + dy[i];
            if(a >= 0 && a < m && b >= 0 && b < n && vis[a][b] == false && matrix[x][y] < matrix[a][b])
            {
                tmp++;
                vis[a][b] = true;
                dfs(a, b, matrix);
                tmp--;
                vis[a][b] = false;
            }
        }
    }
};

2、记忆化搜索:

class Solution {
public:
    int ans = 0;
    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
    bool vis[201][201];
    int m, n;
    // 记忆化搜索优化:记录以特定位置开头的最长递增路径
    int memo[201][201];
    int longestIncreasingPath(vector<vector<int>>& matrix) {
        m = matrix.size();
        n = matrix[0].size();
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                ans = max(ans, dfs(i, j, matrix));
            }
        }
        return ans;
    }
    int dfs(int x, int y, vector<vector<int>>& matrix)
    {
        // 先查
        if(memo[x][y])
            return memo[x][y];
        // 边界+逻辑
        int ret = 1;
        for(int i = 0; i < 4; i++)
        {
            int a = x + dx[i];
            int b = y + dy[i];
            if(a >= 0 && a < m && b >= 0 && b < n && matrix[x][y] < matrix[a][b])
                ret = max(ret, dfs(a, b, matrix) + 1);
        }
        memo[x][y] = ret;
        return memo[x][y];
    }
};

以下是动态规划和记忆化搜索的共性:

记忆化搜索动态规划
dfs函数含义确定状态表示
dfs函数体设计推到状态转移方程
dfs函数出口初始化
填备忘录顺序填dp表顺序
dfs函数返回值返回dp表中合适值

二、例题

1、斐波那契数列

509. 斐波那契数 - 力扣(LeetCode)

2、不同路径

62. 不同路径 - 力扣(LeetCode)

3、最长递增子序列

300. 最长递增子序列 - 力扣(LeetCode)

4、猜数字大小

375. 猜数字大小 II - 力扣(LeetCode)

5、矩阵中的最长递增路径

329. 矩阵中的最长递增路径 - 力扣(LeetCode)

三、总结

有意往动态规划问题上靠的话会发现 dfs 函数的设计都是和 dp 表一模一样,但是如果要用暴搜写逻辑代码就是截然不同,而且还超时,所以再次强调不要思考暴搜逻辑,一定错!!!!!!一定要思考动态规划逻辑!!!!!!

记忆化搜索考虑三个部分:先看有没有记录,再看边界,最后中间逻辑。

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

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

相关文章

uniapp小程序自定义中间凸起样式底部tabbar

我自己写的自定义的tabbar效果图 废话少说咱们直接上代码&#xff0c;一步一步来 第一步&#xff1a; 找到根目录下的 pages.json 文件&#xff0c;在 tabBar 中把 custom 设置为 true&#xff0c;默认值是 false。list 中设置自定义的相关信息&#xff0c; pagePath&#x…

app专项测试(网络测试流程)

一、网络测试的一般流程 step1&#xff1a;首先要考虑网络正常的情况 ① 各个模块的功能正常可用 ② 页面元素/数据显示正常 step2&#xff1a;其次要考虑无网络的情况 ① APP各个功能在无网络情况下是否可用 ② APP各个页面之间切换是否正常 ③ 发送网络请求时是…

【Kubernetes Pod间通信-第3篇】Kubernetes中Pod与ClusterIP服务之间的通信

引言 我们之前了解了在不同场景下,Kubernetes中Pod之间的通信是如何路由的。 【Kubernetes Pod间通信-第1篇】在单个子网中使用underlay网络实现Pod到Pod的通信【Kubernetes Pod间通信-第2篇】使用BGP实现Pod到Pod的通信现在,我们来看看在集群中,Pod与服务之间的通信是如何…

【免费】2007-2019年各省科技支出占一般公共预算支出的比重数据

2007-2019年各省科技支出占一般公共预算支出的比重数据 1、时间&#xff1a;2007-2019年 2、来源&#xff1a;国家统计局、统计年鉴 3、指标&#xff1a;行政区划代码、地区名称、年份、科技支出占一般公共预算支出的比重 4、范围&#xff1a;31省 5、指标解释&#xff1a…

【LeetCode】day15 142.环形链表II

142. 环形链表 II - 力扣&#xff08;LeetCode&#xff09; 题目描述 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则…

C基础(六)指针,指针的基础概念、变量定义、运算、大小等

指针&#xff1a; 什么是指针&#xff1a;指针表示内存地址&#xff0c;平时所说的指针一般是保存地址的指针变量。定义指针变量 格式&#xff1a;数据类型 *指针变量名。初始化和赋值&#xff1a;指针指向变量的首地址。定义指针后若未赋值则为野指针&#xff1b;可将变量地址…

【R语言】获取数据

R语言自带2种数据存储格式&#xff1a;*.RData和*.rds。 这两者的区别是&#xff1a;前者既可以存储数据&#xff0c;也可以存储当前工作空间中的所有变量&#xff0c;属于非标准化存储&#xff1b;后者仅用于存储单个R对象&#xff0c;且存储时可以创建标准化档案&#xff0c…

央行发布《贸易金融分布式账本技术要求》,参考架构包括5部分

《银行科技研究社》(作者 木子剑):2024年12月11日,中国人民银行发布金融行业标准《贸易金融分布式账本技术要求》(JR/T 0308-2024)(以下简称“《要求》”),当日实施。据悉,该文件的起草单位包括6大行和多家股份制银行等。 《要求》规定了分布式账本技术在贸易金融领域…

CSS盒模型详解:从零开始理解margin、border、padding

引言 在CSS中&#xff0c;盒模型(Box Model)是一个非常基础且重要的概念。它定义了网页中每个元素如何占据空间以及元素间的关系。今天&#xff0c;我们就通过简单的例子来理解盒模型的构成。 盒模型的组成部分 CSS盒模型主要由四个部分组成&#xff08;从外到内&#xff09…

DS图(中)(19)

文章目录 前言一、图的遍历广度优先遍历深度优先遍历 二、最小生成树Kruskal算法Prim算法两种方法对比 总结 前言 承上启下&#xff0c;我们来学习下图的中篇&#xff01;&#xff01;&#xff01; 一、图的遍历 图的遍历指的是遍历图中的顶点&#xff0c;主要有 广度优先遍历 …

112,【4】攻防世界 web weak_auth

之前做过&#xff0c;回顾 进入靶场 输入admin 123456 不是&#xff0c;这也行&#xff0c;什么闭合方式&#xff0c;注释符都没用上 反而不自然了 不过输入admin 123456 纯属个人习惯 假如我没那么输&#xff0c;或者用户名&#xff0c;密码不是这两个&#xff0c;我该怎…

蓝桥杯更小的数(区间DP)

题目描述 小蓝有一个长度均为 n 且仅由数字字符 0 ∼ 9 组成的字符串&#xff0c;下标从 0 到 n − 1&#xff0c;你可以将其视作是一个具有 n 位的十进制数字 num&#xff0c;小蓝可以从 num 中选出一段连续的子串并将子串进行反转&#xff0c;最多反转一次。小蓝想要将选出的…

109,【1】攻防世界 web 题目名称-文件包含

进入靶场 直接显示源代码 提示我们通过get方式传递名为filename的参数&#xff0c;同时给出了文件名check.php filenamecheck.php 显示使用了正确的用法&#xff0c;错误的方法 filename./check.php 还是一样的回显 傻了&#xff0c;题目名称是文件包含&#xff0c;需要用到…

71.StackPanel黑白棋盘 WPF例子 C#例子

就是生成黑白棋盘&#xff0c;利用该控件能自动排列的功能。用一个横向的StackPanel嵌套纵向的StackPanel&#xff0c;然后在里面添加设定好长和高的矩形。 因为StackPanel是按照控件的大小展示的。所以如果不设置长和宽。就会显示不出矩形。 <StackPanel Orientation"…

DeepSeek之python实现API应用

先创建一个API KEY https://platform.deepseek.com/api_keys python脚本实现 # Please install OpenAI SDK first: `pip3 install openai`from openai import OpenAIclient = OpenAI(api_key="", base_url="https://api.deepseek.com")response = cli…

MySQL中like模糊查询如何优化?

大家好&#xff0c;我是锋哥。今天分享关于【MySQL中like模糊查询如何优化&#xff1f;】面试题。希望对大家有帮助&#xff1b; MySQL中like模糊查询如何优化&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在MySQL中&#xff0c;LIKE模糊查询通常会影…

通过docker安装部署deepseek以及python实现

前提条件 Docker 安装:确保你的系统已经安装并正确配置了 Docker。可以通过运行 docker --version 来验证 Docker 是否安装成功。 网络环境:保证设备有稳定的网络连接,以便拉取 Docker 镜像和模型文件。 步骤一:拉取 Ollama Docker 镜像 Ollama 可以帮助我们更方便地管理…

制作PE启动盘(内含Win11 iso镜像)

前言 本文用于记录制作PE启动盘过程&#xff0c;学习记录用&#xff0c;如有不对请指出&#xff0c;谢谢&#xff01; 参考视频&#xff1a; 1. 微PE下载&#xff1a;https://www.bilibili.com/video/BV1vT4y1n7JX/?spm_id_from333.788.top_right_bar_window_history.conte…

128陷阱

首先我们了解一下关于包装器类型 java是面向对象的语言&#xff0c;但基本类型并不是面向对象的&#xff0c;从而出现了包装器类型&#xff0c;并且包装器添加了更多的属性和方法。如我们在使用集合类型Collection的时候就一定要使用包装类型而非基本类型&#xff0c;它相当于将…

javaEE-9.HTML入门

目录 一.什么是html 二.认识html标签 1.标签的特点: 2.html文件基本结构 3.标签的层次结构 三、html工具 四、创建第一个文件 五.html常见标签 1标题标签h1-h6 2.段落标签:p 3.换行标签:br 4.图片标签:img 图片路径有1三种表示形式: 5.超链接:a 链接的几种形式: …