[Algorithm][回溯][记忆化搜索][最长递增子序列][猜数字大小Ⅱ][矩阵中的最长递增路径]详细讲解

目录

  • 1.最长递增子序列
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 2.猜数字大小 II
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 3.矩阵中的最长递增路径
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现


1.最长递增子序列

1.题目链接

  • 最长递增子序列

2.算法原理详解

  • 题目解析:从每个位置,依次计算其最长递增子序列
    请添加图片描述

  • 思路选择

    • 暴搜(递归) -> 本题会超时:P
    • 记忆化搜索
    • 动态规划
  • 尝试:暴搜 -> 记忆化搜索 -> 动态规划

  • 暴搜

    • DFS()设计int DFS(nums, pos) -> 每次从pos位置找最长递增子序列
    • 函数体:依次从pos位置往后枚举,更新本次最长递增子序列
  • 本题有大量重复要计算的值,故可以用记忆化搜索

  • 记忆化搜索

    • 备忘录vector<int> mem
    • 返回之前,把结果存在备忘录中
    • 递归之前,查找一下备忘录是否有要找的值
  • 动态规划

    • 注意:本题是前面的值依赖后面的值,所以**填表顺序要从后往前填**

3.代码实现

// v1.0 暴搜
class Solution 
{
public:
    int lengthOfLIS(vector<int>& nums) 
    {
        int ret = 0;
        for(int i = 0; i < nums.size(); i++)
        {
            ret = max(ret, DFS(nums, i));
        }

        return ret;
    }

    int DFS(vector<int>& nums, int pos)
    {
        int ret = 1; // 细节:初值为1

        for(int i = pos + 1; i < nums.size(); i++)
        {
            if(nums[i] > nums[pos])
            {
                ret = max(ret, DFS(nums, i) + 1);    
            }
        }

        return ret;
    }
};
-------------------------------------------------------------------------------
// v2.0 记忆化搜索
class Solution 
{
    vector<int> mem;
public:
    int lengthOfLIS(vector<int>& nums) 
    {
        mem.resize(nums.size());

        int ret = 0;
        for(int i = 0; i < nums.size(); i++)
        {
            ret = max(ret, DFS(nums, i));
        }

        return ret;
    }

    int DFS(vector<int>& nums, int pos)
    {
        if(mem[pos] != 0)
        {
            return mem[pos];
        }

        int ret = 1; // 细节:初值为1
        for(int i = pos + 1; i < nums.size(); i++)
        {
            if(nums[i] > nums[pos])
            {
                ret = max(ret, DFS(nums, i) + 1);    
            }
        }

        mem[pos] = ret;
        return ret;
    }
};
-------------------------------------------------------------------------------
// v3.0 动态规划
int lengthOfLIS(vector<int>& nums) 
{
    int n = nums.size();
    vector<int> dp(n, 1);

    int ret = 0;
    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;
}

2.猜数字大小 II

1.题目链接

  • 猜数字大小 II

2.算法原理详解

  • 题目思路解析

    • 每次给出一个数据范围,从中找出花费最少的一次
    • 但是当一个结点的左右子树返回时,要取最大的,因为要确保"能获胜的最小金额",就要让左右子树的两种情况都能实现
    • 最优解:取最小是在该范围内,每个数对应的最终结果取最小
      请添加图片描述
  • 思路选择

    • 暴搜(递归) -> 本题会超时:P
    • 记忆化搜索
  • 暴搜

    • DFS()设计int DFS(int left, int right) -> 每次从[left, right]区间内找出最小的
    • 函数体:依次遍历[left, right]中的各个数,递归分析左右⼦树,求出所有情况下的最⼩值
    • 递归出口
      • left > right:区间不存在,返回0
      • left == right:就是最后的一个结果,此时无需花钱,返回0
  • 本题有大量重复要计算的值,故可以用记忆化搜索
    请添加图片描述

  • 记忆化搜索

    • 备忘录vector<int> mem
    • 返回之前,把结果存在备忘录中
    • 递归之前,查找一下备忘录是否有要找的值

3.代码实现

// v1.0 暴搜
class Solution 
{
public:
    int getMoneyAmount(int n) 
    {
        return DFS(1, n);
    }

    int DFS(int left, int right)
    {
        if(left >= right)
        {
            return 0;
        }

        int ret = INT_MAX;
        for(int i = left; i <= right; i++) // 选择头结点
        {
            int x = DFS(left, i - 1);
            int y = DFS(i + 1, right);
            ret = min(ret, max(x, y) + i);
        }

        return ret;
    }
};
------------------------------------------------------------------------
// v2.0 记忆化搜索
class Solution 
{
    vector<vector<int>> mem;
public:
    int getMoneyAmount(int n) 
    {
        mem.resize(n + 1, vector(n + 1, 0));
        return DFS(1, n);
    }

    int DFS(int left, int right)
    {
        if(left >= right)
        {
            return 0;
        }

        if(mem[left][right] != 0)
        {
            return mem[left][right];
        }


        int ret = INT_MAX;
        for(int i = left; i <= right; i++) // 选择头结点
        {
            int x = DFS(left, i - 1);
            int y = DFS(i + 1, right);
            ret = min(ret, max(x, y) + i);
        }

        mem[left][right] = ret;
        return ret;
    }
};

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

1.题目链接

  • 矩阵中的最长递增路径

2.算法原理详解

  • 题目解析:遍历数组,对每个位置来一次DFS即可
  • 思路选择
    • 暴搜(递归) -> 本题会超时:P
    • 记忆化搜索
  • 本题有大量重复要计算的值,故可以用记忆化搜索
    请添加图片描述

3.代码实现

// v1.0 暴搜
class Solution 
{
    int n, m;

    // "方向"向量数组
    int dx[4] = {1, -1, 0, 0};
    int dy[4] = {0, 0, 1, -1};
public:
    int longestIncreasingPath(vector<vector<int>>& matrix) 
    {
        n = matrix.size(), m = matrix[0].size();

        int ret = 0;
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < m; j++)
            {
                ret = max(ret, DFS(matrix, i, j));
            }
        }

        return ret;
    }

    int DFS(vector<vector<int>>& matrix, int i, int j)
    {
        int ret = 1;
        for(int k = 0; k < 4; k++)
        {
            int x = i + dx[k], y = j + dy[k];
            if(x >= 0 && x < n && y >= 0 && y < m && matrix[x][y] > matrix[i][j])
            {
                ret = max(ret, DFS(matrix, x, y) + 1);
            }
        }

        return ret;
    }
};
---------------------------------------------------------------------------
// v2.0 记忆化搜索
class Solution 
{
    int n, m;
    vector<vector<int>> mem;

    // "方向"向量数组
    int dx[4] = {1, -1, 0, 0};
    int dy[4] = {0, 0, 1, -1};
public:
    int longestIncreasingPath(vector<vector<int>>& matrix) 
    {
        n = matrix.size(), m = matrix[0].size();
        mem.resize(n, vector<int>(m, 0));

        int ret = 0;
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < m; j++)
            {
                ret = max(ret, DFS(matrix, i, j));
            }
        }

        return ret;
    }

    int DFS(vector<vector<int>>& matrix, int i, int j)
    {
        if(mem[i][j] != 0)
        {
            return mem[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 < n && y >= 0 && y < m && matrix[x][y] > matrix[i][j])
            {
                ret = max(ret, DFS(matrix, x, y) + 1);
            }
        }

        return mem[i][j] = ret;
    }
};

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

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

相关文章

【BUG】Edge|联想电脑 Bing 搜索报错“Ref A: 乱码、 Ref B:乱码、Ref C: 日期” 的解决办法

文章目录 省流版前言解决办法 详细解释版前言问题描述与排查过程解决办法与总结 省流版 我原以为我解决了&#xff0c;才发的博客&#xff0c;晚上用了一下其他设备发现还是会出现这个问题… 这篇博客并未解决该问题&#xff0c;如果评论里有人解决了这个问题不胜感激&#x…

博客说明 5/12~5/24【个人】

博客说明 5/12~5/24【个人】 前言版权博客说明 5/12~5/24【个人】对比最后 前言 2024-5-24 13:39:23 对我在2024年5月12日到5月24日发布的博客做一下简要的说明 以下内容源自《【个人】》 仅供学习交流使用 版权 禁止其他平台发布时删除以下此话 本文首次发布于CSDN平台 作…

Undet for SketchUp 2023.3 点云建模软件 支持支持草图大师sketchup2021-2022-2023

1.Undet for sketchup 2023.3支持草图大师sketchup2021-2022-2023。支持机载雷达扫描、车载扫描还是地面扫描&#xff0c;对AEC行业用户来说&#xff0c;真正需要的是如何将这些数据快速处理为三维模型&#xff0c;这样才能将这些信息延展到BIM领域发挥效用。因此面对这些海量的…

【真实项目中收获的提升】- 前后端联调

场景 小型项目前后端联调&#xff0c;不需要部署到sit或uat环境下。 解决方法 后端部署frp服务 下载frp软件 配置frpc.ini文件&#xff0c;先把文件设置可编辑(可同时配置多个 例如下面的chz 上面打码的是frp服务器地址) 然后起start.bat 其实就是执行frpc -c frpc.ini命令…

4、PHP的xml注入漏洞(xxe)

青少年ctf&#xff1a;PHP的XXE 1、打开网页是一个PHP版本页面 2、CTRLf搜索xml&#xff0c;发现2.8.0版本&#xff0c;含有xml漏洞 3、bp抓包 4、使用代码出发bug GET /simplexml_load_string.php HTTP/1.1 补充&#xff1a; <?xml version"1.0" encoding&quo…

DockerNetwork

Docker Network Docker Network 是 Docker 引擎提供的一种功能&#xff0c;用于管理 Docker 容器之间以及容器与外部网络之间的网络通信。它允许用户定义和配置容器的网络环境&#xff0c;以便容器之间可以相互通信&#xff0c;并与外部网络进行连接。 Docker Network 提供了以…

docker容器安装mysql

linux: centOS-7 hadoop: 3.3.6 前置章节&#xff1a; (图文并茂)基于CentOS-7搭建hadoop3.3.6大数据集群-CSDN博客 可选&#xff1a;zookeeper安装教程-CSDN博客 1.安装docker 1.1 添加docker的repo源 sudo yum-config-manager --add-repo http://mirrors.aliyun.com/…

猫狗电子玩具底层方案开发

物在现代年轻人中的地位已经超越了简单的“宠物”定义&#xff0c;它们已经成为了家庭的一部分&#xff0c;是人们生活中不可或缺的伴侣和朋友。 因此营运而生了很多宠物用品&#xff0c;比如喂食器、电子逗猫棒、饮水机、说话按钮等等宠物电子玩具周边。宠物玩具在宠物生活中…

Python-3.12.0文档解读-内置函数hash()详细说明+记忆策略+常用场景+巧妙用法+综合技巧

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 详细说明 功能描述 参数 返回值 特性 使用示例 注意事项 记忆策略 常用场景 …

【数学建模】储药柜的设计

2014高教社杯全国大学生数学建模竞赛D题目 题目描述 储药柜的结构类似于书橱&#xff0c;通常由若干个横向隔板和竖向隔板将储药柜分割成若干个储药槽(如图1所示)。为保证药品分拣的准确率&#xff0c;防止发药错误&#xff0c;一个储药槽内只能摆放同一种药品。药品在储药槽…

SpringBoot实现增量部署

目录&#xff1a; 1、使用背景2、实现流程3、部署增量包到项目中并启动4、说明 1、使用背景 最近发现公司发布版本时候&#xff0c;很齐全&#xff0c;接口文档&#xff0c;部署方式等都很好&#xff0c;其中有个增量部署包&#xff0c;有点兴趣&#xff0c;不清楚怎么生成增量…

vue3+ts+vant4 实现购物车 前端代码

一、功能效果 二、前端代码 购物车的vue代码 <template><van-nav-bar left-text"返回" title"购物车" click-left"onClickLeft"><template #right><van-popover v-model:show"showPopover" placement"bot…

SQLite数据库免改造透明加密解决方案:给数据加把锁

在数字化时代&#xff0c;信息安全和隐私保护显得尤为重要。TDE透明加密技术&#xff0c;是一种在用户无感知的情况下对数据进行加密和解密的技术。它能够在数据生成、存储、传输和使用过程中自动进行加密处理&#xff0c;无需用户手动操作。透明加密技术的核心在于其透明性&am…

登录接口测试

登录接口测试 数据驱动

java spring cloud 企业工程管理系统源码+二次开发+定制化服务 em

在建筑行业中&#xff0c;工程项目管理软件&#xff08;工程项目管理系统&#xff09;扮演着至关重要的角色&#xff0c;它为建设工程项目管理提供了全方位、全过程的综合管理支持。从项目组织建设、策划决策、规划设计&#xff0c;到施工建设、竣工交付、总结评估&#xff0c;…

丰田精益生产的模板

丰田精益生产&#xff0c;也被称为丰田生产方式&#xff08;Toyota Production System, TPS&#xff09;&#xff0c;是一套完整的生产和管理系统&#xff0c;其核心目标是最大化效率、消除浪费&#xff0c;并通过持续改进来提升产品质量。 学习优秀企业 学习福特 丰田精益生产…

Java对象大小计算与MAT内存泄露分析

文章目录 JVM内存布局对象头实例数据对齐填充 计算实例数组占用内存大小String占用内存大小对象占用内存计算 使用jmap的方式查看Instrumentation计算对象内存方式MAT内存分析示例 JVM内存布局 一个对象主要包含下面3个部分&#xff1a; 对象头(Header)实例数据(Instance Dat…

WAF绕过(下)

过流量检测 这里的流量检测就是在网络层的waf拦截到我们向webshell传输的数据包&#xff0c;以及webshell返回的数据 包&#xff0c;检测其中是否包含敏感信息的一种检测方式。如果是大马的情况下&#xff0c;可以在大马中添加多处判断代码&#xff0c;因此在执行大马提供的功…

最新FinalShell专业版激活

支持的版本 可以激活任意版本的FinalShell为专业版&#xff0c;包括最新版4.3.10 激活方式 打开FinalShell&#xff0c;点击左下角 激活/升级。 账号密码任意输入几个字符&#xff0c;点离线激活。 复制机器码&#xff0c;将机器码发送给微信公众号【小白学算法】见文章末…

如何解决Nginx反向代理不生效?

目录 背景 过程 日志 检查配置文件 重启服务 检查容器内的配置文件 容器和宿主机 其他 背景 用了两年的nginx新加的反向代理不生效 Docker挂载的配置文件启动的Nginx&#xff0c;配置一切正常&#xff0c;但是反向代理不生效&#xff0c;???先自查一波 过程 日志 …