leetcode算法题之记忆化搜索总结

news2024/11/17 17:44:53

记忆化搜索,可以理解为带备忘录的递归,方便进行剪枝,是一种以空间换时间的策略。

本章目录

  • 1.斐波那契数
  • 2.不同路径
  • 3.最长递增子序列
  • 4.猜数字大小II
  • 5.矩阵中的最长递增路径

1.斐波那契数

斐波那契数
在这里插入图片描述

class Solution {
public://递归
    int fib(int n) {
        return dfs(n);
    }
    int dfs(int n)
    {
        if(n==0 || n==1) return n;
        return dfs(n-1)+dfs(n-2);
    }
};

在这里插入图片描述

class Solution {
    int memo[31];
public://递归+记忆化搜索
    int fib(int n) {
        memset(memo,-1,sizeof memo);
        return dfs(n);
    }
    int dfs(int n)
    {
        if(memo[n]!=-1) return memo[n];
        if(n==0 || n==1)
        {
            memo[n] = n;
            return memo[n];
        }
        memo[n] =dfs(n-1)+dfs(n-2);
        return memo[n];
    }
};

在这里插入图片描述

class Solution {
public://动态规划
    int fib(int n) {
        int dp[31];
        dp[0] = 0;
        dp[1] = 1;
        for(int i=2;i<=n;i++)
        {
            dp[i] = dp[i-1]+dp[i-2];
        }
        return dp[n];
    }
};

在这里插入图片描述

从上面可以看出,当出现大量重复的子问题时候,递归转记忆化搜索才有意义,另外,从上面可浅浅的看出,记忆化搜索是一种类型的动态规划,这也是<<算法导论>>这本书里写的,不过,并不是所有的记忆化搜索都能转成动态规划,这是因题而异的,下面的第4和5题就不适合将记忆化搜索转成动态规划。

2.不同路径

不同路径
在这里插入图片描述

class Solution {
public://记忆化搜索
    int uniquePaths(int m, int n) {
        vector<vector<int>> memo(m+1,vector<int>(n+1,0));//备忘录
        return dfs(m,n,memo);
    }
    int dfs(int i,int j,vector<vector<int>>& memo)
    {
        if(memo[i][j]!=0) return memo[i][j];
        if(i==0 || j == 0) return 0;
        if(i == 1&& j == 1)
        {
            memo[i][j] = 1;
            return memo[i][j];
        }
        memo[i][j] = dfs(i-1,j,memo) + dfs(i,j-1,memo);
        return memo[i][j];
    }
};
class Solution {
public://动态规划
    int uniquePaths(int m, int n) {
        //状态表示:从起点到(m,n)有多少种不同的路径
        vector<vector<int>> dp(m+1,vector<int>(n+1,0));
        dp[1][1] = 1;
        for(int i=1;i<=m;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(i==1 && j==1) continue;
                dp[i][j] = dp[i-1][j] + dp[i][j-1];
            }
        }
        return dp[m][n];
    }
};

3.最长递增子序列

最长递增子序列
在这里插入图片描述

class Solution {
public://记忆化搜索
    int lengthOfLIS(vector<int>& nums) {
        int ret = 0;
        int n = nums.size();
        vector<int> memo(n);//备忘录
        for(int i=0;i<n;i++)
        {
            ret = max(ret,dfs(nums,i,memo));
        }
        return ret;
    }
    //dfs作用:以nums[i]为起点的最长递增子序列的长度
    int dfs(vector<int>& nums,int pos,vector<int>& memo)
    {
        if(memo[pos]!=0) return memo[pos];
        int ret = 1;
        for(int i=pos+1;i<nums.size();i++)
        {
            if(nums[i]>nums[pos])
            {
                ret = max(ret,dfs(nums,i,memo)+1);
            }
        }
        memo[pos] = ret;
        return memo[pos];
    }
};
class Solution {
public://动态规划
    int lengthOfLIS(vector<int>& nums) {
        int n = nums.size();
        int ret = 0;
        //以nums[i]为起点的最长递增子序列的长度
        vector<int> dp(n,1);
        //从右往左填
        for(int i = n-1;i>=0;i--)
        {
            for(int j = i+1;j<n;j++)
            {
                if(nums[j]>nums[i])
                {
                    dp[i] = max(dp[i],dp[j]+1);
                }
            }
            ret = max(ret,dp[i]);
        }
        return ret;
    }
};

在这里插入图片描述

从执行时间上来看,这题使用动态规划来解决并不是最优解,用我们之前在贪心里记录的贪心+二分查找来解决更好。

4.猜数字大小II

猜数字大小II
在这里插入图片描述

class Solution {
    int memo[202][202];
public://解题方法:暴搜+记忆化搜索
    int getMoneyAmount(int n) {
        return dfs(1,n);
    }
    //dfs的作用:在区间[i,n],不管你选择区间中的哪个数,我都能获胜的最小现金数
    int dfs(int left,int right)
    {
        if(memo[left][right]!=0) return memo[left][right];
        if(left>=right) return 0;
        int ret =INT_MAX;
        for(int head = left;head<=right;head++)//选择头结点
        {
            int x = dfs(left,head-1);
            int y = dfs(head+1,right);
            ret = min(ret,max(x,y)+head);
        }
        memo[left][right] = ret;
        return ret;
    }
};

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

矩阵中的最长递增路径
在这里插入图片描述

class Solution {
    int memo[201][201];
    int dx[4] = {0,0,1,-1};
    int dy[4] = {1,-1,0,0};
    int m,n;
public:
    int longestIncreasingPath(vector<vector<int>>& matrix) {
        m = matrix.size(), n = matrix[0].size();
        int ret = 0;
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                ret = max(ret,dfs(matrix,i,j));
            }
        }
        return ret;
    }
    //dfs作用:以(i,j)为起点的最长递增路径的长度
    int dfs(vector<vector<int>>& matrix,int i,int j)
    {
        if(memo[i][j]!=0) return memo[i][j];
        int ret = 1;
        for(int k=0;k<4;k++)
        {
            int x = i+dx[k],y = j+dy[k];
            if(x>=0 && x<m && y>=0 && y<n && matrix[x][y]>matrix[i][j])
            {
                ret = max(ret,dfs(matrix,x,y)+1);
            }
        }
        memo[i][j] = ret;
        return ret;
    }
};

leetcode关于递归的题在这就告一段落啦,希望大家通过前面的学习,能力已经有所提高,我们下次再会!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GitEE-GitHub实现加速访问与下载项目

gitee域名&#xff1a;https://gitee.com gitee域名&#xff1a;https://github.com 一、从github导出项目到gitee上面&#xff0c;从而实现加速访问与下载 gitee和github都有同步其他仓库的功能&#xff0c;比如码云上就能直接从github或gitlab中导入&#xff1b; 只需要填…

路由器02_静态路由DHCP

一、静态路由 &#xff11;、静态路由特点 由管理员手工配置&#xff0c;是单向的&#xff0c;缺乏灵活性 &#xff12;、默认路由 默认路由是一种比较特殊静态路由&#xff0c;一般用于末节&#xff08;末梢&#xff09;网络&#xff0c;直接指定目标为任何地方 二、静态…

墨墨智库正式上线:开启您的AI智慧之旅

在这个由数据驱动的时代&#xff0c;AI技术正迅速改变我们的工作和生活方式。有没有想过一个平台可以为您提供所有AI相关资源的便捷访问&#xff1f;这就是「墨墨智库」的使命。我们非常高兴地宣布&#xff0c;经过精心准备和期待&#xff0c;「墨墨智库」现已正式上线&#xf…

深入理解C指针

深入理解C指针 ​#C语言 #​ #C指针 #​ 1 认识指针 指针&#xff1a;一个存放内存地址的变量 1.1 指针和内存 ​​ ‍ 阅读指针声明时候&#xff0c;可以选择倒过来读&#xff0c;会更容易理解。 指针被赋值为NULL时候&#xff0c;会被解释为二进制0. void指针 具有和…

docker 安装elasticsearch、kibana、cerebro

安装步骤 第一步安装 docker 第二步 拉取elasticsearch、kibana、cerebro 镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:7.10.2 docker pull docker.elastic.co/kibana/kibana:7.10.2 docker pull lmenezes/cerebro:latest第三步、创建 容器 创建e…

SQL Server从0到1——写shell

xp_cmdshell 查看能否使用xpcmd_shell&#xff1b; select count(*) from master.dbo.sysobjects where xtype x and name xp_cmdshell 直接使用xpcmd_shell执行命令&#xff1a; EXEC master.dbo.xp_cmdshell whoami 发现居然无法使用 查看是否存在xp_cmdshell: EXEC…

深入理解计算机系统(1):开始

计算机系统是由硬件和系统软件组成的&#xff0c;它们共同工作来运行应用程序。虽然系统的具体实现方式随着时间不断变化&#xff0c;但是系统内在的概念却没有改变。所有计算机系统都有相似的硬件和软件组件&#xff0c;它们又执行着相似的功能。 计算机系统 信息就是位上下…

❀记忆冒泡、选择和插入排序算法思想在bash里运用❀

目录 冒泡排序算法:) 选择排序算法:) 插入排序算法:) 冒泡排序算法:) 思想&#xff1a;依次比较相邻两个元素&#xff0c;重复的进行直到没有相邻元素需要交换&#xff0c;排序完成。 #!/bin/bash arr(12 324 543 213 65 64 1 3 45) #定义一个数组 n${#arr[*]} #获取数组…

非工程师指南: 训练 LLaMA 2 聊天机器人

引言 本教程将向你展示在不编写一行代码的情况下&#xff0c;如何构建自己的开源 ChatGPT&#xff0c;这样人人都能构建自己的聊天模型。我们将以 LLaMA 2 基础模型为例&#xff0c;在开源指令数据集上针对聊天场景对其进行微调&#xff0c;并将微调后的模型部署到一个可分享的…

【STM32】STM32学习笔记-定时器定时中断 定时器外部时钟(14)

00. 目录 文章目录 00. 目录01. 定时器中断相关API1.1 TIM_InternalClockConfig1.2 TIM_TimeBaseInit1.3 TIM_TimeBaseInitTypeDef1.4 TIM_ClearFlag1.5 TIM_ITConfig1.6 TIM_Cmd1.7 中断服务函数1.8 TIM_ETRClockMode2Config 02. 定时器定时中断接线图03. 定时器定时中断示例0…

每日算法打卡:数的范围 day 7

文章目录 原题链接题目描述输入格式输出格式数据范围输入样例&#xff1a;输出样例&#xff1a; 题目分析示例代码 原题链接 789. 数的范围 题目难度&#xff1a;简单 题目描述 给定一个按照升序排列的长度为 n 的整数数组&#xff0c;以及 q 个查询。 对于每个查询&#…

数字孪生在虚拟现实(VR)中的应用

数字孪生在虚拟现实&#xff08;VR&#xff09;中的应用为用户提供了更深入、沉浸式的体验&#xff0c;同时通过数字孪生技术模拟真实世界的物理实体。以下是数字孪生在VR中的一些应用&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发…

12月笔记

#pragma once 防止多次引用头文件&#xff0c;保证同一个&#xff08;物理意义上&#xff09;文件被多次包含&#xff0c;内容相同的两个文件同样会被包含。 头文件.h与无.h的文件&#xff1a; iostream是C的头文件&#xff0c;iostream.h是C的头文件&#xff0c;即标准的C头文…

电话号码信息收集工具:PhoneInfoga | 开源日报 No.137

sundowndev/phoneinfoga Stars: 11.2k License: GPL-3.0 PhoneInfoga 是一个用于扫描国际电话号码的信息收集框架&#xff0c;它允许用户首先收集基本信息 (如国家、地区、运营商和线路类型)&#xff0c;然后使用各种技术来尝试找到 VoIP 提供商或识别所有者。该工具与一系列必…

[MySQL]视图索引以及连接查询案列

目录 1.视图 1.1视图是什么 1.2视图的作用 1.3操作 1.3.1创建视图 1.3.2视图的修改 1.3.3删除视图 1.3.4查看视图 2.索引 2.1什么是索引 2.2为什么要使用索引 2.3索引的优缺点 2.3.1优点 2.3.2缺点 2.4索引的分类 3.连接查询案列 4.思维导图 1.视图 1.1视图是什么 视图…

代码随想录-刷题第四十九天

121. 买卖股票的最佳时机 题目链接&#xff1a;121. 买卖股票的最佳时机 思路&#xff1a;动态规划五步曲 dp[i][0] 表示第i天持有股票所得最多现金&#xff0c;dp[i][1] 表示第i天不持有股票所得最多现金。 一开始现金是0&#xff0c;那么加入第i天买入股票&#xff0c;现金…

深入了解 RDD

深入了解 RDD 案例 明确需求&#xff1a; 在访问日志中&#xff0c;统计独立IP数量 TOP10 查看数据结构&#xff1a; IP&#xff0c;时间戳&#xff0c;Http&#xff0c;Method&#xff0c;Url…… 明确编码步骤 取出IP&#xff0c;生成一个只有IP的数据集简单清洗统计IP出现…

Tomcat Notes: Deployment File

This is a personal study notes of Apache Tomcat. Below are main reference material. - YouTube Apache Tomcat Full Tutorial&#xff0c;owed by Alpha Brains Courses. https://www.youtube.com/watch?vrElJIPRw5iM&t801s 1、Tomcat deployment1.1、Two modes of …

数据结构与算法教程,数据结构C语言版教程!(第二部分、线性表详解:数据结构线性表10分钟入门)九

第二部分、线性表详解&#xff1a;数据结构线性表10分钟入门 线性表&#xff0c;数据结构中最简单的一种存储结构&#xff0c;专门用于存储逻辑关系为"一对一"的数据。 线性表&#xff0c;基于数据在实际物理空间中的存储状态&#xff0c;又可细分为顺序表&#xff…

Java 基础知识点1 (含面试题)

本次Java 知识点主要是关于SE的相关基础&#xff0c;同时也包含了数据结构中的一些API&#xff0c;例如Set,List,Map等&#xff0c;最后也附上了相关重要的面试题&#xff0c;可供大家学习与参考&#xff01; 目录 重要知识点数据结构API面试题 重要知识点 Java 是一门面向对象…