【Leetcode】动态规划 刷题训练(八)

news2024/11/17 7:52:53

文章目录

  • 413. 等差数列划分
    • 状态转移方程
    • 完整代码
  • 978. 最长湍流子数组
    • 题目解析
    • 状态转移方程
      • f[i]状态转移方程
      • g[i]状态转移方程
    • 完整代码
  • 139. 单词拆分
    • 状态转移方程
    • 初始化
    • 完整代码

413. 等差数列划分

点击查看:等差数列划分


如果一个数列 至少有三个元素 ,并且任意两个相邻元素之差相同,则称该数列为等差数列。
例如,[1,3,5,7,9]、[7,7,7,7] 和 [3,-1,-5,-9] 都是等差数列。
给你一个整数数组 nums ,返回数组 nums 中所有为等差数组的 子数组 个数。
子数组 是数组中的一个连续序列。

示例 1:
输入:nums = [1,2,3,4]
输出:3
解释:nums 中有三个子等差数组:[1, 2, 3]、[2, 3, 4] 和 [1,2,3,4] 自身。
示例 2:
输入:nums = [1]
输出:0


状态转移方程

dp[i]:表示以i位置元素为结尾的所有子数组中等差数列的个数


若ABCD为等差数列,而D与B C也能形成等差数列,ABCDE也是一个等差数列


若想求以i为结尾的所有子数组的等差数列的个数,
而子数组是连续的,想要构成等差数列,至少使i位置与 i-1和i-2位置构成等差数列


dp[i]分为两种情况

情况1:i i-1 i-2位置元素 可以构成等差数列

假设i-2位置元素为a,i-1位置元素为b,i位置元素为c
则三者之间的差值相同,即 c-b==b-a

v以a b 为结尾的等差数列 ,由于c 与a b 也能构成等差数列,所以 以 a b c 为结尾也为等差数列
而以 a b为结尾 就相当于 以 b为结尾 即dp[i-1](以i-1位置为结尾的所有等差数列的个数)
而a b c 属于等差数列 ,且不在dp[i-1]的情况之内 ,所以 需要+1

该情况下: dp[i]=dp[i-1]+1


情况2:i i-1 i-2位置元素 不构成等差数列

假设i-2位置元素为a,i-1位置元素为b,i位置元素为c
则三者之间的差值不同 即 c-b不等于b-a

因为子数组是连续的,而a b c不构成等差数列,前面构不构成等差数列就没有意义了
该情况下: dp[i]=0


状态转移方程为:
dp[i]= c-b==b-a?dp[i-1]+1:0

完整代码

class Solution {
public:
    int numberOfArithmeticSlices(vector<int>& nums) {
         int n=nums.size();
         vector<int>dp(n,0);
         int i=0;
         int sum=0;
         for(i=2;i<n;i++)
         {
             //状态转移方程
             dp[i]=nums[i]-nums[i-1]==nums[i-1]-nums[i-2]?dp[i-1]+1:0;
             sum+=dp[i];
         }
         //返回dp表中所有值之和
         return sum;
    }
};

由于等差数列要求至少有三个元素,当只有一个/两个元素时,不满足要求,所以dp[0]=0 dp[1]=0

978. 最长湍流子数组

点击查看:最长湍流子数组

给定一个整数数组 arr ,返回 arr 的 最大湍流子数组的长度 。
如果比较符号在子数组中的每个相邻元素对之间翻转,则该子数组是 湍流子数组 。
更正式地来说,当 arr 的子数组 A[i], A[i+1], …, A[j] 满足仅满足下列条件时,我们称其为湍流子数组:
若 i <= k < j :
当 k 为奇数时, A[k] > A[k+1],且
当 k 为偶数时,A[k] < A[k+1];
或 若 i <= k < j :
当 k 为偶数时,A[k] > A[k+1] ,且
当 k 为奇数时, A[k] < A[k+1]。

示例 1:
输入:arr = [9,4,2,10,7,8,8,1,9]
输出:5
解释:arr[1] > arr[2] < arr[3] > arr[4] < arr[5]
示例 2:
输入:arr = [4,8,12,16]
输出:2


题目解析

B的值比A大,则呈现上升趋势
C的值比B小,则呈现下降趋势
D的值比C大,则呈现上升趋势
则ABCD数组为湍流子数组

状态转移方程

dp[i]:表示 以i位置为结尾的所有子数组中,最长的湍流数组的长度

刚开始分析写出dp[i],但是会发现湍流数组有上升和下降趋势的问题,而dp[i]无法解决,所以再次定义f[i]和g[i]


f[i]:表示以i位置为结尾的所有子数组中,最后呈现上升趋势的最长湍流数组的长度


g[i]:表示以i位置为结尾的所有子数组中,最后呈现下降趋势的最长湍流数组的长度


f[i]状态转移方程

假设i-1位置的元素的值为a,i位置的元素值为b


情况1 a>b

与前面数组结合 只能呈现下降趋势
若想自己呈现上升趋势,单独1个构成子数组,最后一个位置既可以上升,也可以下降
即 f[i]=1


情况2 a<b

此时呈现上升趋势,符合f[i]的含义

再次寻找以i-1位置为结尾,最后呈现下降趋势的湍流数组的最长的长度 即g[i-1]
再加上由a到b的长度 即+1
该情况下: f[i]=g[i-1]+1


情况3 a==b

在该情况下想要使i位置处呈现上升趋势,只能单独1个构成子数组
即 f[i]=1

g[i]状态转移方程

假设i-1位置的元素的值为a,i位置的元素值为b


情况1 a>b

此时正好呈现下降趋势, 符合g[i]含义

再次寻找以i-1位置为结尾,最后呈现上升趋势的湍流数组的最长的长度 即f[i-1]
再加上由a到b的长度 即+1

该情况下:g[i]=f[i-1]+1


情况2 a<b

在该情况下想要使i位置处呈现下降趋势,只能单独1个构成子数组
即g[i]=1


情况3 a==b

在该情况下想要使i位置处呈现下降趋势,只能单独1个构成子数组
即g[i]=1

完整代码

class Solution {
public:
    int maxTurbulenceSize(vector<int>& nums) {
       int n=nums.size();
       //f g表 都表示湍流数组的最长长度
       //而单独一个数本身,表示最低长度为1
       //所以f/g 最差长度也为1
       vector<int>f(n,1);
       vector<int>g(n,1);

       int i=0;
       //单独一个数 返回1 ,所以初始值为1
       int fmax=1;
       int gmax=1;
       for(i=1;i<n;i++)
       {
           //f[i] a<b情况
           if(nums[i-1]<nums[i])
           {
               f[i]=g[i-1]+1;
           }
           //g[i] a>b情况
           else if(nums[i-1]>nums[i])
           {
               g[i]=f[i-1]+1;
           }
           fmax=max(fmax,f[i]);
           gmax=max(gmax,g[i]);
       }
       //返回 f和g表中的最大值
       return max(fmax,gmax);
    }
};

单独一个数本身,可以构成上升或者下降趋势 ,所以湍流数组 长度最差也为1
所以可以把f/g表中里面的元素全部初始化为1

139. 单词拆分

点击查看:单词拆分


给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。
注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

示例 1:
输入: s = “leetcode”, wordDict = [“leet”, “code”]
输出: true
解释: 返回 true 因为 “leetcode” 可以由 “leet” 和 “code” 拼接成。
示例 2:
输入: s = “applepenapple”, wordDict = [“apple”, “pen”]
输出: true
解释: 返回 true 因为 “applepenapple” 可以由 “apple” “pen” “apple” 拼接成。
注意,你可以重复使用字典中的单词。
示例 3:
输入: s = “catsandog”, wordDict = [“cats”, “dog”, “sand”, “and”, “cat”]
输出: false

状态转移方程

dp[i]:表示 [0,i]区间内的字符串,能否被字典中的单词拼接而成
若能够拼接而成,则返回true ,若不能则返回false

根据最后一个位置来划分问题


若能确定前面这个部分能够拼接成功,并且保证 最后一个单词在字典中,整体字符串就能被拼接而成

设j作为最后一个单词的起始位置的下标
j的范围为 0<=j<=i
0表示整个字符串作为最后一个单词
i表示最后一个字符作为最后一个单词


字符串的起始位置为0
j作为最后一个单词的起始位置,所以字符串的终止位置为j-1

[0,j-1]区间内的字符串 需要判断是否能被字典中的单词拼接而成 即dp[j-1]
最后一个单词的范围是 [j,i] ,这段区间内的子串是否在字典中


状态转移方程为:
当dp[i-1] 为true 并且 最后一个单词([j-i]范围内)在字典中 两者都满足 ,结果才为true
若有任意一个不成立,则为false

初始化

当j为0时,会发生越界问题

为了防止这种越界问题出现,所以加入一个虚拟节点
扩展后的数组,虚拟节点处下标为0,则 原数组的元素下标从1开始


若j为0,表示把0到i这个区间整个看作是最后一个单词,若最后一个单词在字典中,要返回true,
dp[0]=true
这样才能保证两者都为true


假设原始字符串为s ,辅助位置一般是空格
s=’ ’ +s
原始字符串加上辅助位置后,原始字符串相当于从1开始计数,正好与新的dp表对应

完整代码

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        unordered_set<string>hash;
        for(auto& s:wordDict)
        {
           hash.insert(s);
        }
         int n=s.size();
         //为了防止越界问题,所以多加一个虚拟节点
         vector<bool>dp(n+1);
         //初始化
         dp[0]=true;
         s=' '+s;//使原始字符串的下标统一+1
         int i=0;
         int j=0;
         for(i=1;i<=n;i++)
         {
             for(j=i;j>=1;j--)
             {
                 //在hash中判断 s中对应的子串在不在 若在返回1 不在返回0
                 if(  dp[j-1]&&  hash.count(s.substr(j,i-j+1)) )
                 {
                     dp[i]=true;
                     break;//找到一种情况即可
                 }
             }
         }
         //因为多加了个虚拟节点,所以下标+1
         return dp[n];
    }
};

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

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

相关文章

【操作系统】键盘敲入字母时,操作系统期间发生了什么?

【操作系统】键盘敲入字母时&#xff0c;操作系统期间发生了什么&#xff1f; 参考资料&#xff1a; 键盘敲入 A 字母时&#xff0c;操作系统期间发生了什么&#xff1f; 【操作系统】浅谈 Linux 中的中断机制 文章目录 【操作系统】键盘敲入字母时&#xff0c;操作系统期间发…

小驰私房菜_26_YUV数据存在数据对齐,工具打开花图时如何处理?

【问题背景】 在Qcom Camx框架下&#xff0c;dump的yuv,yuv数据有时会存在数据对齐&#xff0c;也就是app端下发的size和我们dump出来的size是不一致的。 这个时候&#xff0c;我们用yuv工具查看yuv数据的时候&#xff0c;宽高如果直接设置的app端下发的size&#xff0c;这个时…

案例解析 | 虚拟数智人“岭梅香”——民间博物馆文化探寻者

TA 是湾区民间文化探寻者 还是广东民间博物馆宣传大使 万里归来颜愈少 笑时犹带“岭梅香” 虚拟数智人 是文博行业走进“元宇宙”的“探路者” 为了践行国家文化数字化战略&#xff0c;按照文化和旅游部“上云用数赋智”的要求&#xff0c;南方都市报、N视频联合广州虚拟…

MATLAB Onramp

目录 任务 音频频率 以表的形式导入数据 循环 恒星运动 知识点摘要 任务 您可以按键盘上的向上箭头键重新调用以前的命令。请注意&#xff0c;要执行此操作&#xff0c;命令行窗口必须为活动窗口。 按向上箭头键以回到命令 m3*5&#xff0c;然后将该命令编辑为 m3*k cle…

【209. 长度最小的子数组】

目录 一、题目解析二、算法原理三、代码实现 一、题目解析 二、算法原理 注意点&#xff1a; 三、代码实现 我自己写的代码(我的评价是很挫) class Solution { public:int minSubArrayLen(int target, vector<int>& nums) {int left 0, right -1, ret INT_MAX…

【算法与数据结构】28、LeetCode找出字符串中第一个匹配项的下标

文章目录 一、题目二、暴力穷解法三、KMP算法四、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、暴力穷解法 思路分析&#xff1a;首先判断字符串是否合法&#xff0c;然后利用for循环&#xff0c;取出子字符串…

Flutter卡片分享功能实现:将你的内容分享给世界

前言 在app中&#xff0c;在实现分享功能的时候&#xff0c;通常会有一种以卡片形式展示和分享内容的分享方式。这种功能可以将信息以整洁、易读的方式呈现给用户&#xff0c;使他们能够快速了解内容的关键信息&#xff0c;并将其分享给其他人。那么在这篇文章中&#xff0c;就…

【1004.最大连续1的个数Ⅲ】

目录 一、题目解析二、算法思路三、代码实现 一、题目解析 二、算法思路 三、代码实现 class Solution { public:int longestOnes(vector<int>& nums, int k) {int ret0,count0;int left0,right0;for (; right < nums.size();right ){if (nums[right] 0){count;…

C++——string容器常用操作汇总

纵有疾风起&#xff0c;人生不言弃。本文篇幅较长&#xff0c;如有错误请不吝赐教&#xff0c;感谢支持。 &#x1f4ac;文章目录 一.string容器基本概念二.string容器常用操作✅前言及函数参数的说明一.构造和析构二.string特性操作三.字符操作四.赋值操作五.拼接操作六.交换…

Ubuntu安装gcc和g++图文教程

文章目录 一、gcc 和 g介绍二、ubuntu安装gcc和g三、gcc和g的选项总结 一、gcc 和 g介绍 GCC&#xff08;GNU Compiler Collection&#xff09;是由GNU项目开发的一套广泛使用的开源编译器集合。它支持多种编程语言&#xff0c;包括C、C、Objective-C、Fortran、Ada和其他语言…

基于python深度学习的水果或其他物体识别小程序

效果图如下&#xff1a; 代码演示和demo仓库看b站视频003期&#xff1a; 到此一游7758258的个人空间_哔哩哔哩_bilibili 代码展示&#xff1a; 数据集图片放置在data文件夹下&#xff0c;大家可以根据自己需要比如识别其他物体&#xff0c;只需要模仿data文件夹下的文件命名放…

浅谈基于分项计量的校园能源监管平台解决方案设计

张心志 关注acrelzxz 安科瑞电气股份有限公司 上海嘉定 201801 摘要&#xff1a;伴随着我国经济的飞速发展&#xff0c;国家机关办公建筑和大型公共建筑高耗能的问题日益突出&#xff0c;如何解决建筑能耗己成为一个国家总能耗的重要组成部分。学校是肩负着教育、科研和社会服…

Oracle中的连接方式

Oracle中的连接方式 对于数据库中表与表之间的连接&#xff08;内连接、外连接&#xff09;都可以看成集合之间的运算操作。 内连接 select * from a_table a inner join b_table b on a.id b.id; 相当于求两个集合中满足条件的结果&#xff0c;即交集。 外连接 左/外连接&a…

计算机性能

计算机性能 计算机性能描述 计算机性能测试程序 计算机性能速度指标 计算机性能计算 设1号计算机执行任务耗时3s,2号计算机执行任务耗时2s&#xff0c;则有 P11/3 P21/2 则相对性能比为 P1/P22/3 &#xff08;p1的性能为p2性能的2/3&#xff09;&#xff0c;因为P1/P2 < …

软考A计划-系统集成项目管理工程师-项目范围管理(一)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…

Echarts折线图折线呈现为渐变线条

想要如图所示的折线图&#xff0c;折线线条为渐变颜色&#xff0c;两边颜色接近区域面积的颜色&#xff0c;中间颜色亮度高一些&#xff0c;在series中使用lineStyle&#xff0c;将其color设置为渐变色&#xff1a; option {xAxis: {type: category,data: [Mon, Tue, Wed, Th…

ModaHub魔搭社区:向量数据库Milvus性能优化问题(二)

目录 为什么有时候小的数据集查询时间反而更长&#xff1f; 为什么查询时 GPU 一直空闲&#xff1f; 为什么数据插入后不能马上被搜索到&#xff1f; 为什么我的 CPU 利用率始终不高&#xff1f; 创建集合时 index_file_size 如何设置能达到性能最优&#xff1f; 为什么有…

0基础学习VR全景平台篇 第53篇:专业版功能-离线导出!

大家好&#xff0c;欢迎观看蛙色VR官方系列——后台使用课程&#xff01; 本期为大家带来蛙色VR平台&#xff0c;专业版功能-离线导出&#xff01; 功能位置示意 一、本功能将用在哪里&#xff1f; 离线导出&#xff0c;指的是将VR漫游作品通过下载的方式&#xff0c;保存到本…

YOLOv5/v7 添加注意力机制,30多种模块分析⑦,CCN模块,GAMAttention模块

目录 一、注意力机制介绍1、什么是注意力机制&#xff1f;2、注意力机制的分类3、注意力机制的核心 二、CCN模块1、CCN模块的原理2、实验结果3、应用示例 三、GAMAttention模块1、GAMAttention模块的原理2、实验结果3、应用示例 大家好&#xff0c;我是哪吒。 &#x1f3c6;本…

FreeRTOS内核API速览

FreeRTOS内核API速览 信号量创建信号量计数信号量互斥信号量二值信号量 释放信号量任务模式中断模式 获取信号量任务模式中断模式 消息队列创建队列发送消息任务模式中断模式 获取消息任务模式中断模式 软件定时器创建定时器启动定时器停止定时器复位定时器删除定时器改变定时器…