【LeetCode】动态规划 刷题训练(九)

news2024/11/26 5:58:06

文章目录

  • 环绕字符串中唯一的子字符串
    • 题目解析
    • 状态转移方程
    • 返回值
    • 完整代码
  • 最长递增子序列
    • 子数组与子序列的区别
    • 状态转移方程
    • 完整代码
  • 摆动序列
    • 题目解析
    • 状态转移方程
      • f[i]状态转移方程
      • g[i]状态转移方程
    • 完整代码

环绕字符串中唯一的子字符串

点击查看:467. 环绕字符串中唯一的子字符串


定义字符串 base 为一个 “abcdefghijklmnopqrstuvwxyz” 无限环绕的字符串,所以 base 看起来是这样的:
“…zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd…”.
给你一个字符串 s ,请你统计并返回 s 中有多少 不同非空子串 也在 base 中出现。

示例 1:
输入:s = “a”
输出:1
解释:字符串 s 的子字符串 “a” 在 base 中出现。
示例 2:
输入:s = “cac”
输出:2
解释:字符串 s 有两个子字符串 (“a”, “c”) 在 base 中出现。

题目解析

若以c开头,则可分为 c ca cac
若以a开头,则可分为 a ac
若以最后一个c开头,则可分为c

在环绕字符串中去寻找 上述六种字符串,发现只有 c a 符合要求
所以只有两种

状态转移方程

dp[i] 表示 以i位置的元素为结尾的所有的子串里面,有多少个在base中出现过


dp[i]分为两种情况

情况1:i位置元素本身(长度为1)
在base中包含a-z的所有字母,所以单独一个字母肯定在base中出现
即该情况下长度为1


情况2:i位置元素与前面元素结合(长度大于1)

想要求以i位置的元素为结尾的所有的子串里面,有多少个在base中出现过
就需要先求i-1位置的元素为结尾的所有的子串里面,有多少个在base中出现 即dp[i-1]
然后再加上i位置的元素即可
需要保证以 i-1位置为结尾的子串加上i位置元素也要在base中出现


情况1:base是由a到z连续组成
由i-1位置的字符ASCII值+1 即可为i位置的字符的ASCII值 即s[i-1]+1==s[i]


情况2:base是由z到a 跳跃组成
i-1位置的字符为z,i位置的字符为a 即s[i-1]==‘z’ && s[i] ==‘a’

两种情况满足一个时,才为符合条件的子字符串

返回值

对于上述字符串,若返回值计算的是dp表的所有值之和
则会计算重复的子串ac ca ,导致结果错误
所以需要去重


两个字符串都是以d字符为结尾的,若都计算就会造成重复
所以当相同字符结尾,将dp值较大的进行累加 ,将dp值较小的舍去

完整代码

class Solution {
public:
    int findSubstringInWraproundString(string s) {
          int n=s.size();
          //在base中包含a-z的所有字母,所以单独一个字母肯定在base中出现
          //所以将dp表初始化为1
          vector<int>dp(n,1);
         //创建大小为26的数组,用于统计以i位置2为结尾的dp值
         //将dp值大的进行累加 将dp值小的舍去
         //以此达到去重
         vector<int>arr(26,0);
          int i=0;
          int ret=0;
          for(i=1;i<n;i++)
          {
              if(s[i-1]+1==s[i]||s[i-1]=='z'&&s[i]=='a')
              {
                  dp[i]+=dp[i-1];
              }
          }
          //遍历dp表 取其中重复子串的dp最大值
          for(i=0;i<n;i++)
          {
              arr[s[i]-'a']=max(arr[s[i]-'a'],dp[i]);
          }
          for(auto&e:arr)
          {
              ret+=e;
          }
          //返回arr数组的和
          return ret; 
    }
};

最长递增子序列

点击查看:300. 最长递增子序列


给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

示例 1:
输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
示例 2:
输入:nums = [0,1,0,3,2,3]
输出:4

子数组与子序列的区别

子序列:按照从左到右的顺序,任意挑选几个 所组成的新序列 即为子序列
如:a b d 为子序列 跳过了c ,但相对顺序与原数组保持一致(d在原数组中就在a b后,新的数组也是如此)
而 d a b 就不是一个子序列了

子数组:按照从左到右的顺序,任意挑选的必须是连续的
如:a b c为子数组 ,但 a b d就不是子数组

状态转移方程

dp[i] 表示 以i位置元素为结尾的所有的子序列中,最长的递增子序列的长度


dp[i]分为两种情况


情况1:i位置元素本身(长度为1)
只有i位置元素本身,所以该情况下最长的递增子序列的长度为1


情况2:i位置元素和前面元素结合(长度大于1)

想要求 以i位置元素为结尾的所有的子序列中,最长的递增子序列的长度
就需要先求 区间[0,i-1]内的最长的递增子序列的长度(因为子序列是相对顺序所以有可能不在i-1位置取最长长度)
( 假设区间[0,i-1]为j)
再加上i位置元素长度 即+1

由于是递增子序列,就需要使j位置的元素小于i位置元素
即 nums[j]<nums[i]

由于j是一个区间,所以在区间内寻找最大值
即 dp[i]= max(dp[j]+1)

完整代码

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int n=nums.size();
        //由于最差的情况是取i位置元素本身 即最长的递增长度为1
        //所以初始化为1
        vector<int>dp(n,1);
        int i=0;
        int j=0;
        for(i=1;i<n;i++)
        {
            for(j=0;j<i;j++)
            {
                //再保证是一个递增子序列的情况下
                if(nums[j]<nums[i])
                {
                   dp[i]=max(dp[i],dp[j]+1);
                }
            }
        }
        int ret=INT_MIN;
        //遍历dp表寻找最大值
        for(i=0;i<n;i++)
        {
          ret=max(ret,dp[i]);
        }
        //返回dp表最大值
        return ret;
    }
};

摆动序列

点击查看:376. 摆动序列


如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。
例如, [1, 7, 4, 9, 2, 5] 是一个 摆动序列 ,因为差值 (6, -3, 5, -7, 3) 是正负交替出现的。
相反,[1, 4, 7, 2, 5] 和 [1, 7, 4, 5, 5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。
子序列 可以通过从原始序列中删除一些(也可以不删除)元素来获得,剩下的元素保持其原始顺序。
给你一个整数数组 nums ,返回 nums 中作为 摆动序列 的 最长子序列的长度 。

示例 1:
输入:nums = [1,7,4,9,2,5]
输出:6
解释:整个序列均为摆动序列,各元素之间的差值为 (6, -3, 5, -7, 3) 。

题目解析

正常情况下,每次需要保证一上一下才能为摆动序列


单独一个元素也视为摆动序列
或者两个元素不相等,也被视为摆动序列

状态转移方程

dp[i]:表示以i位置为结尾的所有子序列中,最长的摆动序列的长度


f[i]:表示以i位置为结尾的所有子序列中,最后一个位置呈现上升趋势 的 最长的摆动序列的长度


g[i]:表示以i位置为结尾的所有子序列中,最后一个位置呈现下降趋势 的 最长的摆动序列的长度

f[i]状态转移方程

情况1:i位置元素本身(长度为1)
单独一个元素可以为一个摆动序列,即最长的摆动序列的长度为1


情况2:i位置元素与前面元素集结合(长度大于1)

想要求 以i位置元素为结尾的所有的子序列中,最后一个位置呈现上升趋势的最长的摆动序列的长度
就需要先求 区间[0,i-1]内的最后一个位置呈现下降趋势的最长的摆动序列的长度(因为子序列是相对顺序所以有可能不在i-1位置取最长长度)
( 假设区间[0,i-1]为j)
再加上i位置元素长度 即+1
即g[j]+1
由于j是一个区间,所以取 区间中的最大值 即 f[i]=max(g[j]+1,f[i]);

最后一个位置呈现上升趋势,就需要加上限制条件 :使j位置的元素小于i位置元素
即 nums[j]<nums[i]

g[i]状态转移方程

情况1:i位置元素本身(长度为1)
单独一个元素可以为一个摆动序列,即最长的摆动序列的长度为1


情况2:i位置元素与前面元素集结合(长度大于1)

想要求 以i位置元素为结尾的所有的子序列中,最后一个位置呈现下降趋势的最长的摆动序列的长度
就需要先求 区间[0,i-1]内的最后一个位置呈现上升趋势的 最长的摆动序列的长度(因为子序列是相对顺序所以有可能不在i-1位置取最长长度)
( 假设区间[0,i-1]为j)
再加上i位置元素长度 即+1
即f[j]+1
由于j是一个区间,所以取 区间中的最大值 即 g[i]=max(f[j]+1,g[i]);

最后一个位置呈现下降趋势,就需要加上限制条件 :就需要使j位置的元素大于i位置元素
即 nums[j]>nums[i]

完整代码

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
     int n=nums.size();
     //创建f表(最后一个位置呈现上升趋势)
     //g表(最后一个位置呈现下降趋势)j
     vector<int>f(n,1);
     vector<int>g(n,1);
     int i=0;
     int j=0;
     //只有一个元素时也为摆动序列 所以最低长度为1
     int ret=1;
     for(i=1;i<n;i++)
     {
           for(j=0;j<i;j++)
           {
               //在保证j位置元素小于i位置元素
              if(nums[j]<nums[i])
              {
                  f[i]=max(g[j]+1,f[i]);
              }
              //在保证j位置元素大于i位置元素
              if(nums[j]>nums[i])
              {
                  g[i]=max(f[j]+1,g[i]);
              }
           }
           //取f表和g表中的最大值
           ret=max(max(ret,f[i]),g[i]);
     }
     //返回f和g表 两者中的最大值
     return ret;
    }
};

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

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

相关文章

Flutter——最详细(NavigationBar)使用教程

NavigationBar简介 Material 3 导航栏组件! 导航栏提供了一种持久且便捷的方式来在应用程序的主要目的地之间进行切换。 使用场景&#xff1a; 底部菜单栏模块 属性作用onDestinationSelected选择索引回调监听器selectedIndex目前选定目的地的索引destinations存放菜单按钮back…

Filter的四大插件(grok、date、mutate、mutiline)

Filter的四个插件 一、grok 正则捕获插件1、grok 的概念2、内置正则表达式调用3、常用的常量NetworkingpathsMonths: January, Feb, 3, 03, 12, DecemberDays: Monday, Tue, Thu, etc...Years?Syslog Dates: Month Day HH:MM:SSShortcutsLog formatsLog Levels 3、自定义表达式…

49. 字母异位词分组

题目链接&#xff1a;力扣 解题思路&#xff1a;字母异位词分组也就是将&#xff1a;字母以及字母个数都相同的单词组合成一组&#xff0c;然后返回结果&#xff0c;比如ate&#xff0c;eat&#xff0c;tea都是由1个a&#xff0c;1个t&#xff0c;1个e组成。 所以&#xff0c…

【python基础】python中的with关键字及其相关用法

目录 1.with关键字 2.上下文管理器 3.总结 4.with torch.no_grad()的用法 在Python中&#xff0c;with是一个关键字&#xff0c;用于处理上下文管理器&#xff08;context manager&#xff09;。上下文管理器是一种对象&#xff0c;它定义了在进入和离开某个上下文时应该执…

7.12~7.13学习总结

public static void main(String[] args){File dirnew File("D:\\小花花");boolean flag dir.mkdir();System.out.println(flag);File dirsnew File("D:\\小花花\\你爸爸");dirs.mkdirs();String[]adir.list();//列出下一级&#xff1b;字符串数组for(Stri…

了解 JVM - 认识垃圾回收机制与类加载过程

前言 本篇通过介绍JVM是什么&#xff0c;认识JVM的内存区域的划分&#xff0c;了解类加载过程&#xff0c;JVM中垃圾回收机制&#xff0c;从中了解到垃圾回收机制中如何找到存活对象的方式&#xff0c;引用计数与可达性分析的方式&#xff0c;再释放垃圾对象时使用的方式&…

【YOLO】yolov5的训练策略1 -- 训练热身warmup

目录 一、什么是训练热身二、常见的训练热身1. Constant Warmup2. Linner Warmup2. Cosine Warmup 三、yolov5的训练热身代码 一、什么是训练热身 众所周知学习率是一个非常重要的超参数&#xff0c;直接影响着网络训练的速度和收敛情况。通常情况下&#xff0c;网络开始训练之…

DNS 是如何影响你冲浪速度的?

本文详细介绍了 DNS 相关知识&#xff0c;包括 DNS 工作原理、如何提升域名解析速度、以及 DNS 记录与报文等内容。 1. 域名与域名服务器 在日常上网过程中&#xff0c;出于好记的原因&#xff0c;人们更喜欢在浏览器中输入网站的域名&#xff0c;而不是 IP 地址。比如想要访问…

小红书如何运营 策略方法总结

大家好&#xff0c;我是权知星球&#xff0c;今天跟大家分享一下小红书如何运营和策略方法总结。 小红书是一个生活方式和消费决策平台&#xff0c;并为用户提供入口&#xff0c;作为一个生活方式社区&#xff0c;小红书的独特之处在于其用户发布的内容都来自于真实生活&#…

MySQL-DDL-数据库操作

开发项目流程 数据库设计-DDL DDL&#xff1a;Data Definition Language&#xff0c;数据定义语言&#xff0c;用来定义数据库对象&#xff08;数据库、表&#xff09; 数据库 常见操作 查询 查询所有数据库&#xff1a;show databases&#xff1b; 查询当前数据库&#xf…

A Simple Framework for Contrastive Learning of Visual Representations(论文翻译)

A Simple Framework for Contrastive Learning of Visual Representations 摘要1介绍2 方法2.1 对比学习框架2.2 训练大批量数据2.3 评估协议 3.用于对比表示学习的数据增强3.1.数据增强操作的组合对于学习良好的表示至关重要3.2 对比学习需要更强的数据增强比有监督学习 4. 编…

STM32单片机WIFI阿里云老人智能家居语音识别定时吃药

实践制作DIY- GC00158-WIFI阿里云老人智能家居语音识别定时吃药 一、功能说明&#xff1a; 基于STM32单片机设计------WIFI阿里云老人智能家居语音识别定时吃药 二、功能说明&#xff1a; 电路组成&#xff1a;STM32F103CXT6最小系统LD3322语音识别模块LCD1602显示按键1个ULN2…

【网络安全】渗透测试工具——Burp Suite

渗透测试工具Burp Suite主要功能详解 前言一、 Proxy模块1.1 界面布局1.1.1 菜单栏&#xff08;1&#xff09; 菜单栏 Burp&#xff08;2&#xff09; 菜单栏 project&#xff08;3&#xff09; 菜单栏 Intruder&#xff08;4&#xff09; 菜单栏 Repeater&#xff08;5&#x…

微信小程序开发:必须掌握的 HTML、CSS 和 JavaScript 技术

引言 小程序是一种轻量级的应用程序&#xff0c;通过HTML、CSS和JavaScript等前端技术开发&#xff0c;可在移动设备上直接访问和使用&#xff0c;无需下载和安装。 文章目录 引言一、小程序开发的背景和重要性二、HTML、CSS和JavaScript在小程序开发中的作用三、HTML基础知识1…

一篇文章搞定《JVM的完美图解》

一篇文章搞定《JVM的完美图解》 前言常见的问题1、双亲委托机制2、类加载过程加载链接初始化 3、JVM内存结构图方法区堆栈本地方法栈程序计数器 4、对象的组成对象头示例数据对齐字节 5、JVM中怎么确定一个对象是否可以GC引用计数法&#xff08;早期策略&#xff09;可达性分析…

Java设计模式之行为型-中介者模式(UML类图+案例分析)

目录 一、基础概念 二、UML类图 三、角色设计 四、案例分析 五、总结 一、基础概念 中介者模式的核心思想是引入一个中介者对象&#xff0c;来封装和管理对象之间的交互关系。 对象之间不再直接交互&#xff0c;而是通过中介者间接交互。这样可以减少对象之间的依赖&…

浏览器调试技巧

浏览器调试技巧 文章将介绍几个 devtools 技巧。 缩放devtool ui 可能对于某些开发来说devtools 中的文本和按钮太小&#xff0c;使用起来不舒服。而浏览器也提供了可以缩放 devtools UI的方法。 devtools 的用户界面是使用 HTML、CSS 和 JavaScript 构建的&#xff0c;这意…

中国地图数据可视化制作,python的pyecharts模块读取excel中国着色地图可视化

数据格式如下&#xff1a; import pandas as pd from pyecharts import options as opts from pyecharts.charts import Map from pyecharts.globals import ChartType# 读取Excel数据 data pd.read_excel(C:\\Users\\Administrator\\Desktop\\国内数据.xlsx)# 创建地图实例 m…

大学英语四六级考点听力案例-内蒙古民族大学外国语学院四六级考试听力电台

大学英语四六级考点听力案例-内蒙古民族大学外国语学院四六级考试听力电台 北京海特伟业科技有限公司发布于2023年7月13日 文/任洪卓 一、大学英语四六级考点听力广播系统用户需求 内蒙古民族大学位于内蒙古东部通辽市&#xff0c;是一所综合型民族大学&#xff0c;为内蒙古自…

电子水尺——实时监测、高精度测量

法国作家雨果说过&#xff1a;一个城市的良心是下水道。当洪水四溢时&#xff0c;城市的下水道让滔滔之水悄然排淌&#xff0c;城市回归安详。 往期&#xff0c;水位监测总是“被动”执行&#xff0c;这样的做法不仅效率低下&#xff0c;还难以做到及时调度和合理应对。 山东…