代码随想录训练营打卡第36天:动态规划解决子序列问题

1.300最长递增子序列

1.问题描述

找到其中最长严格递增子序列的长度。

子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。

2.问题转换

从nums[0...i]的最长的递增的子序列

3.解题思路

  1. 每一个位置的nums[i]都有两种状态:是否放入
  2. 对于放入状态:找到从[0..j](j<i)之间的递增子序列,如果满足递增,放入子序列中,找到其中最长的那个递增子序列,更新长度。
  3. 对于不放入状态:如果不满足递增,则不放入。

4.为什么使用动态规划?

因为从[0..i]的最长的递增子序列状态一定是由[0..j]的状态递推出来,所以考虑使用动态规划的方法。

5.动态规划的具体实现

  1. dp[j]数组的含义:代表的是从nums[0..j]的最长递增子序列。
  2. 递推公式:for(int i = 0;i<j;i++){        if(nums[j]>nums[i]){//首先需要满足递增                    dp[j] = max(dp[j],dp[i]+1);//从中选择最长的作为最长递增子序列.dp[i] +1:其中i可以等效为背包问题里面的j-weight[i],1可以等效为背包问题里面的value[i].              }          }
  3. 初始化:默认情况下每个的都是1,因为自身可以当做唯一的那一个递增子序列。
  4. 遍历顺序:由递推公式可以知道,应该是满足从小到大的方式进行遍历。

6.进阶:使用动态规划和二分法来解决

1.思路

我们使用一个数组tail用来存放从[0..i]的单调递增数组的尾数(而且对应的nums[i]越小越好),tail[i]代表的是尾数,i代表的是长度。

2.具体实现

1.遍历数组得到此时的nums[i],根据nums[i]在tail数组中找到能够满足的最左侧的位置。

2.最左侧的位置的查找:使用二分法来找到满足严格递增的最长的长度。可能会出现两种情况:

        1.left<res(即在tails的范围内)当tails[mid]<nums[i],tails[left]>nums[i]:此时将tails[left] = nums[i],可以保证在后面运行的时候能够尽可能的找到更长的长度。

        2.当left == res(即这个数比最右侧的那个递增的都长)。此时res++;tails[left] = nums[i].

3.最后的返回值就是对应的一个res的长度。

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        /*//方法1:动态规划
        int n = nums.size();
        vector<int> dp(n,1);//dp[j]:从0-j数组的最长的递增子序列
        int result = 1;
        for(int j = 1;j<n;j++){
            for(int i = 0;i<j;i++){
                if(nums[j]>nums[i]){
                    dp[j] = max(dp[j],dp[i]+1);
                }
            }
            if(result<dp[j])result = dp[j];
        }
        return result;
        */
        //方法2:动态规划+二分查找
        int n = nums.size();
        vector<int> tails(n,0);//用来存放一个单调递增的数组的尾数
        int res = 0;//代表的是单调递增的最大长度
        for(auto num:nums){
            //用于在tail数组中找到需要替换的那个位置tails[i]<num<tails[i+1],此时将其替换为tails[i+1] = num;
            //如果这个值在这个里面找不到,就放在最右边,同时res++;
            int left = 0,right = res;
            while(left<right){//[left,right)循环不变量
                int mid = left +(right - left)/2;
                if(tails[mid]<num)left = mid+1;
                else right = mid;
            }
            tails[left] = num;
            if(res == right) res++;
        }
        return res;

    }
};

2.647最长连续递增子序列

1.问题描述

找到其中最长连续递增子序列的长度。

2.问题转换

从nums[0...i]的最长的连续递增的子序列

3.解题思路

  1. 每一个位置的nums[i]都有两种状态:是否放入
  2. 对于放入状态:nums[i]>nums[i-1],则放入。
  3. 对于不放入状态:如果不满足递增,则不放入。

4.为什么使用动态规划?

因为从[0..i]的最长的递增子序列状态一定是由前一个的状态递推出来,所以考虑使用动态规划的方法。

5.动态规划的具体实现

  1. dp[j]数组的含义:代表的是从nums[0..j]的最长连续递增子序列。(也可以将其表示为以i为结尾的最长的连续递增子序列,然后求解得到最大值)
  2. 递推公式:if(nums[i]>nums[i-1]){//满足递增才能添加
                    tail[i] = tail[i-1]+1;
                }//if(result>tail[i])tail[i] = result;//比较找到最大值
  3. 初始化:默认情况下每个的都是1,因为自身可以当做唯一的那一个递增子序列。
  4. 遍历顺序:由递推公式可以知道,应该是满足从小到大的方式进行遍历。
class Solution {
public:
    int findLengthOfLCIS(vector<int>& nums) {
        int n = nums.size();
        //vector<int> dp(n,1);
        vector<int> tail(n,1);
        int result = 1;
        int i = 0;
        for(int i = 1;i<n;i++){
            if(nums[i]>nums[i-1]){
                tail[i] = tail[i-1]+1;
            }
        }
        auto maxs =  max_element(tail.begin(),tail.end());
        return *maxs;
        /*
        for(int j = 1;j<n;j++){
            i = j;
            for(;i>0;i--){
                if(nums[i]<=nums[i-1]){
                    break;
                }
            }
            dp[j] = max(dp[j-1],(j-i+1));//长度
        }
        return dp[n-1];*/
    }
};

3.718最长重复子数组

1.问题描述

找到其中最长重复子数组的长度。

2.问题转换

按照顺序遍历,如果相同了就长度+1

3.解题思路

  1. 每一个位置的nums[i]都有两种状态:是否相等
  2. 对于相等状态:即nums1[i-1] == nums2[j-1],此时长度+1,然后比较最大值,更新res
  3. 对于不相等状态:比较最大值更新res
  4. 将最大值存放在res中

4.为什么使用动态规划?

因为每一个位置的值都可以由前面的状态或者当前的状态确定。

5.动态规划的具体实现

  1. dp[i][j]数组的含义:代表的是从nums1[0..i-1],nums2[0..j-1]的重复子数组长度。(
  2. 递推公式: if(nums1[i-1] == nums2[j-1]){dp[i][j] = dp[i-1][j-1]+1;}
  3. 初始化:默认情况下每个的都是1,因为自身可以当做唯一的那一个递增子序列。
  4. 遍历顺序:由递推公式可以知道,应该是满足从小到大的方式进行遍历。
  5. 最终结果存放在res中,因为res的含义是最长的重复子数组的长度。
class Solution {
public:
    int findLength(vector<int>& nums1, vector<int>& nums2) {
        int m = nums1.size();
        int n = nums2.size();
        vector<vector<int>> dp(m+1,vector<int>(n+1,0));
        int res = 0;
        for(int i = 1;i<m+1;i++){
            for(int j = 1;j<n+1;j++){
                if(nums1[i-1] == nums2[j-1]){
                    dp[i][j] = dp[i-1][j-1]+1;
                }
                if(dp[i][j]>res) res = dp[i][j];
            }
            
        }
        return res;
    }
};

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

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

相关文章

WebRTC | 网络传输协议 RTP 和 RTCP

WebRTC | 网络传输协议 RTP 和 RTCP WebRTC | 网络传输协议 RTP 和 RTCP如何选择 TCP 与 UDPRTP概述工作机制报文结构RTP 的使用RTP 拓展头RTP 中的填充数据翻译器和混合器同步控制报文大小wireshark 抓取 RTP 报文 RTCP概述工作机制分组类型报文结构WebRTC 的反馈报文RTPFBPSF…

鸿蒙系统和安卓系统通过termux搭建Linux系统—Centos

目录 1. 前言 2. 效果图展示 3. 安装termux 4. 安装Centos系统 4.1 更换源 4.2 拉取镜像 4.3 启动centos 5.结尾 1. 前言 大家好&#xff0c;我是jiaoxingk 今天这篇文章让你能够在手机或者平板上使用Linux-Centos系统 让你随时随地都能操作命令行进行装13 2. 效果图展示…

【电子学会】2023年09月图形化一级 -- 保护环境

保护环境 1. 准备工作 &#xff08;1&#xff09;删除角色小猫&#xff0c;添加角色Wizard&#xff0c;Bear-walking&#xff1b; &#xff08;2&#xff09;添加背景Desert和Forest。 2. 功能实现 &#xff08;1&#xff09;调整魔法师和熊的大小为50&#xff1b; &…

docker搭建gitlab及默认密码修改及配置修改

推荐官方文档 https://docs.gitlab.com/17.0/ee/install/docker.html 我使用的是docker run的方式&#xff0c;官方文档后面有docker-compose、swarm、k8s的部署文档 版本说明 1&#xff1a;可以部署gitlab-ce社区版和gitlab-ee企业版&#xff0c;然后&#xff0c;鉴于是个人…

交叉编译程序,提示 incomplete type “struct sigaction“ is not allowed

问题描述 incomplete type "struct sigaction" is not allowed解决办法 在代码的最顶端添加如下代码即可 #define _XOPEN_SOURCE此定义不是简单的宏定义&#xff0c;是使程序符合系统环境的不可缺少的部分 _XOPEN_SOURCE为了实现XPG&#xff1a;The X/Open Porta…

SpringIOCDI—第一讲

文章目录 什么是IOC什么是控制&#xff0c;谁控制谁什么是反转&#xff0c;从什么反转到什么了 IOC的注解五大类注解Controller注解&#xff08;控制器存储&#xff09;Service&#xff08;服务存储&#xff09;Repository&#xff08;仓库存储&#xff09;Componet(组件存储)C…

大语言模型实战——最小化agent

1. agent是什么 大模型拥有语言理解和推理能力后&#xff0c;就相当于拥有了大脑&#xff0c;要让模型发挥更大的潜力&#xff0c;就需要给它安装上手臂&#xff0c;让它拥有行动的能力。 而Agent就是一个将语言模型和外部工具结合起来的智能体&#xff0c;它使用语言模型的推…

安全设计 | Microsoft 威胁建模工具Threat Modeling Tool安装及使用详解(文末附样例)

1. 概览 微软威胁建模工具&#xff08;Threat Modeling Tool&#xff09;是 Microsoft 安全开发生命周期 (SDL&#xff0c;Security Develop LifeCycle) 的核心要素。 当潜在安全问题处于无需花费过多成本即可相对容易解决的阶段&#xff0c;软件架构师可以使用威胁建模工具提…

人工智能再现大脑细胞导航的活动模式

人工智能再现大脑细胞导航的活动模式 李升伟 编译 深度学习算法可自发模拟特殊神经元的活动&#xff0c;这种神经元活动可以告诉我们在空间的位置。 大鼠使用被称为网格细胞的大脑细胞帮助它们导航&#xff0c;人工智能程序已经可以再现这种能力。 科学家已经使用人工智能来再…

【STM32+k210项目】基于AI技术智能语音台灯的设计(完整工程资料源码)

视频演示 基于AI技术智能语音台灯的设计 前言&#xff1a; 随着社会的快速发展&#xff0c;人们对家用电器智能化程度的要求越来越高。不管是对于学生人群还是对于工作加班者&#xff0c;台灯是每家每户必不可少的工具&#xff0c;长期处于光线太强或者过弱的环境中学习和一系列…

用户账户的权限管理

用户账户的权限管理 用户账号&#xff1a; 1、超级用户 &#xff1a;管理员账号 root 默认对本机拥有最高权限的账户&#xff0c;在系统中唯一。 2、普通用户&#xff1a;一般由管理员创建&#xff0c;拥有的权限是受限制的&#xff0c;一般只在自己的家目录中拥有完整的权限…

每日练习之排序——链表的合并;完全背包—— 兑换零钱

链表的合并 题目描述 运行代码 #include<iostream> #include<algorithm> using namespace std; int main() { int a[31];for(int i 1;i < 30;i)cin>>a[i];sort(a 1,a 1 30);for(int i 1;i < 30;i)cout<<a[i]<<" ";cout&…

走进创新高地,探索职业未来——记大学生参观刺掌信息科技学习活动

在这个向阳生长&#xff0c;充满活力的5月&#xff0c;一群来自江苏大学的充满朝气与求知欲的大学生们来我司参观学习&#xff0c;他们带着对网络安全的热爱和职业生涯的憧憬&#xff0c;走进我们的企业&#xff0c;开始了探索之旅。 交流会上&#xff0c;江苏刺掌信息科技有限…

Python使用multiprocessing实现多进程

大家好&#xff0c;当我们工作中涉及到处理大量数据、并行计算或并发任务时&#xff0c;Python的multiprocessing模块是一个强大而实用的工具。通过它&#xff0c;我们可以轻松地利用多核处理器的优势&#xff0c;将任务分配给多个进程并同时执行&#xff0c;从而提高程序的性能…

CTFHUB技能树——SSRF(二)

目录 上传文件 ​FastCGI协议 Redis协议 上传文件 题目描述&#xff1a;这次需要上传一个文件到flag.php了.祝你好运 index.php与上题一样&#xff0c;使用POST请求的方法向flag.php传递参数 //flag.php页面源码 <?phperror_reporting(0);if($_SERVER["REMOTE_ADDR&…

“从根到叶:使用决策树导航数据”

目录 一、说明 二、什么是决策树&#xff1f; 三、基本概念&#xff1a; 四、工作原理&#xff1a; 五、分类原理分析 5.1 信息熵&#xff1a; 5.2 信息增益&#xff1a; 5.3 基尼杂质&#xff1a; 5.4 基尼系数和熵的区别&#xff1a; 六、对于回归决策树&#xff1a; 6.1 均方…

OR-Oncology Research 肿瘤学研究

文章目录 一、期刊简介二、征稿信息三、期刊表现四、投稿须知五、投稿咨询 一、期刊简介 Oncology Research以临床前和临床癌症治疗为特色&#xff0c;发表了高质量的同行评审研究&#xff0c;有助于在分子生物学、细胞生物学、生物化学、生物物理学、遗传学、生物学、内分泌学…

128天的创意之旅:从初心到成就,我的博客创作纪念日回顾

文章目录 &#x1f680;机缘&#xff1a;初心的种子——回望创作之旅的启航&#x1f308;收获&#xff1a;成长的果实——128天创作之旅的宝贵馈赠❤️日常&#xff1a;创作与生活的交织&#x1f44a;成就&#xff1a;代码的艺术&#x1f6b2;憧憬&#xff1a;未来的蓝图 &…

【RabbitMQ】SpringAMQP--消息转换器

SpringAMQP–消息转换器 测试发送Object类型消息 1.声明队列 Configuration public class FanoutConfig {Beanpublic Queue objectQueue(){return new Queue("object.queue");} }运行消费者后&#xff1a; 2.发送消息 RunWith(SpringRunner.class) SpringBootTes…

01.爬虫---初识网络爬虫

01.初识网络爬虫 1.什么是网络爬虫2.网络爬虫的类型3.网络爬虫的工作原理4.网络爬虫的应用场景5.网络爬虫的挑战与应对策略6.爬虫的合法性总结 1.什么是网络爬虫 网络爬虫&#xff0c;亦称网络蜘蛛或网络机器人&#xff0c;是一种能够自动地、系统地浏览和收集互联网上信息的程…