【OJ】动规练习六

2024-04-04 23:36
文章标签 练习 oj 动规

本文主要是介绍【OJ】动规练习六,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

个人主页 : zxctscl
如有转载请先通知

题目

  • 1. 413. 等差数列划分
    • 1.1 分析
    • 1.2 代码
  • 2. 978. 最长湍流子数组
    • 2.1 分析
    • 2.2 代码
  • 3. 139. 单词拆分
    • 3.1 分析
    • 3.2 代码

1. 413. 等差数列划分

在这里插入图片描述

1.1 分析

一、题目解析:
至少有三个元素才能构成等差数列,题目要求返回的是子序列等差数列的个数

二、算法原理:

  1. 状态表示
    以i位置为结尾,找所有子数组中有多少个等差数列
    dp[i]表示以i位置为结尾的所有子数组中有多少个等差数列。

  2. 状态转移方程
    在这里插入图片描述
    子数组是连续的,如果i位置是等差数列的子序列,那么它前面的两个至少也是构成等差数列。

第一种:考虑abc构成等差数列:c-b=b-a
如果abc能构成等差数列,那么以ab结尾的所有的等差数列再加上一个c也是等差数列。
以ab为结尾,也就是以b为结尾,那么以b结尾的所有子数组等差数列就有dp[i-1]个。但是ab就不在这个数列里面,可abc能构成等差数列,但是也多了一种,所以得多加一个1,这里的1是多加了abc这样的一种情况。

第二种:考虑abc不构成等差数列:c-b≠b-a
那么前面的数再多也不能构成等差数列,此时dp[i]=0。

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

  1. 初始化
    在这里插入图片描述
    因为要三个才能构成等差数列,所以
    dp[0]=0
    dp[1]=0

  2. 填表顺序
    从左往右

  3. 返回值
    题目要求返回的不一定是最后一个位置的值,而是所有子序列等差数列的个数,所以得全部加起来。返回值就是dp表中所以元素的和。
    在这里插入图片描述

1.2 代码

class Solution {
public:int numberOfArithmeticSlices(vector<int>& nums) {int n=nums.size();vector<int> dp(n);if(n<=2)return 0;int sum=0;for(int 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];}return sum;}
};

2. 978. 最长湍流子数组

在这里插入图片描述

2.1 分析

一、题目解析:
湍流数组意思是相邻两个元素大小一升一降
在这里插入图片描述
像题目给的例子1就是在第二个位置4和第三个位置都是降的就不行2。而到了第七个位置8和第六个位置8是平的没有变化,就不是湍流数组,所以例1的最大湍流数组长度就是5。
在这里插入图片描述
在例2中都是升的,所以最大湍流数组长度就是2。
在这里插入图片描述
在例1中只有一个元素,所以最大湍流数组长度就是1。
在这里插入图片描述

二、算法原理:

  1. 状态表示
    以某一个位置为结尾
    如果以dp[i]表示以i位置为结尾的所以子数组中,最长的湍流数组长度,那么可能会出现三种情况最后一个位置可能会出现下降趋势,也可能是上升趋势,还可以是水平的,一个状态表示不能满足情况,所以得换状态表示。
    **f[i]表示i位置为结尾的所以子数组中,最后呈现“上升”**状态下,最长的湍流数组长度
    **g[i]表示i位置为结尾的所以子数组中,最后呈现“下降”**状态下,最长的湍流数组长度

  2. 状态转移方程
    在f[i]中会出现三种情况,第一种:i-1大于i,这样就不能呈现上升状态,所以i位置自己成为上升状态。第二种:i-1小于i,刚好呈现上升状态,接下来就要i-1位置为结尾成下降状态,就是g[i-1]。第三种,i位置的值和i位置相同,就得自己成为上升状态。
    在这里插入图片描述

在g[i]中会出现两种情况,第一种:i-1小于i,这样就不能呈现下降状态,所以i位置自己成为下降状态。第二种:i-1打于i,刚好呈现下降状态,接下来就要i-1位置为结尾成上升状态,就是f[i-1]。第三种,i位置的值和i位置相同,就得自己成为下降状态。
在这里插入图片描述

  1. 初始化

在f表和g表中最差的情况就是1,所以把表中元素全部初始化为1。这样就减少了很多判断情况。

  1. 填表顺序
    从左往右
    两个表一起填

  2. 返回值
    返回f表和g表中最大的那个
    在这里插入图片描述

2.2 代码

class Solution {
public:int maxTurbulenceSize(vector<int>& arr) {int n=arr.size();vector<int> f(n,1),g(n,1);int ret=1;for(int i=1;i<n;i++){if(arr[i-1]<arr[i]){f[i]=g[i-1]+1;}else if(arr[i-1]>arr[i]){g[i]=f[i-1]+1;}ret=max(ret,max(f[i],g[i]));}return ret;}
};

3. 139. 单词拆分

在这里插入图片描述

3.1 分析

一、题目解析:
在给的 wordDict 字典里面可以重复使用某一个单词,还没有要求全部使用。
看一下给的例2:s里面给的字符串就可以在wordDict 字典里面找到就返回true。
在这里插入图片描述
例3:第一单词不管是选择cat还是cats最后剩下的og在wordDict 字典里面都没有找到,就返回false。
在这里插入图片描述

二、算法原理:

  1. 状态表示
    以某一个位置为结尾
    dp[i]表示以i位置为结尾的[0,i]区间内的字符串,能否被字典中的单词拼接而成。能被拼接而成就是true,不能就是false。

  2. 状态转移方程
    根据最后一个位置的情况来划分问题:前面那一部分单词,加上最后一个单词,而最后一个单词中的i,只要能确定前面部分能拼接而成,并且最后一个单词在wordDict 字典里面能找到,那么这个字符串就能拼接而成。
    在这里插入图片描述
    那么在设一个变量j来作为左边部分的最后一个下标,左边这个字符串的开始在0,结尾在j-1,这个区间能否作为字典中的单词拼接而成就是dp[j-1],右边这个位置就[j,i]组成的单词是否在字典中就行。左右两种情况都为true的时候就能拼接。
    在这里插入图片描述

  3. 初始化

为了dp[j-1]不越界,就加一个虚拟节点。为了保证后面的填表顺序是正确,那么dp[0]=true。
还得注意下标的映射关系,这里加了一个新节点,那么s表就得加一个辅助字符。

  1. 填表顺序
    从左往右

  2. 返回值
    题目要求返回是s字符串能否被拼接,就是dp[n]。
    在这里插入图片描述

3.2 代码

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;for(int i=1;i<=n;i++){for(int j=i;j>=1;j--){if(dp[j-1]&&hash.count(s.substr(j,i-j+1))){dp[i]=true;break;}}}return dp[n];}
};/*  */

有问题请指出,大家一起进步!!!

这篇关于【OJ】动规练习六的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/877100

相关文章

RabbitMQ练习(AMQP 0-9-1 Overview)

1、What is AMQP 0-9-1 AMQP 0-9-1(高级消息队列协议)是一种网络协议,它允许遵从该协议的客户端(Publisher或者Consumer)应用程序与遵从该协议的消息中间件代理(Broker,如RabbitMQ)进行通信。 AMQP 0-9-1模型的核心概念包括消息发布者(producers/publisher)、消息(messages)、交换机(exchanges)、

【Rust练习】12.枚举

练习题来自:https://practice-zh.course.rs/compound-types/enum.html 1 // 修复错误enum Number {Zero,One,Two,}enum Number1 {Zero = 0,One,Two,}// C语言风格的枚举定义enum Number2 {Zero = 0.0,One = 1.0,Two = 2.0,}fn m

MySql 事务练习

事务(transaction) -- 事务 transaction-- 事务是一组操作的集合,是一个不可分割的工作单位,事务会将所有的操作作为一个整体一起向系统提交或撤销请求-- 事务的操作要么同时成功,要么同时失败-- MySql的事务默认是自动提交的,当执行一个DML语句,MySql会立即自动隐式提交事务-- 常见案例:银行转账-- 逻辑:A给B转账1000:1.查询

html css jquery选项卡 代码练习小项目

在学习 html 和 css jquery 结合使用的时候 做好是能尝试做一些简单的小功能,来提高自己的 逻辑能力,熟悉代码的编写语法 下面分享一段代码 使用html css jquery选项卡 代码练习 <div class="box"><dl class="tab"><dd class="active">手机</dd><dd>家电</dd><dd>服装</dd><dd>数码</dd><dd

014.Python爬虫系列_解析练习

我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈 入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈 虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈 PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈 Oracle数据库教程:👉👉 Oracle数据库文章合集 👈👈 优

如何快速练习键盘盲打

盲打是指在不看键盘的情况下进行打字,这样可以显著提高打字速度和效率。以下是一些练习盲打的方法: 熟悉键盘布局:首先,你需要熟悉键盘上的字母和符号的位置。可以通过键盘图或者键盘贴纸来帮助记忆。 使用在线打字练习工具:有许多在线的打字练习网站,如Typing.com、10FastFingers等,它们提供了不同难度的练习和测试。 练习基本键位:先从学习手指放在键盘上的“家位”开始,通常是左手的

anaconda3下的python编程练习-csv翻译器

相关理解和命令 一、环境配置1、conda命令2、pip命令3、python命令 二、开发思路三、开发步骤 一、环境配置 1、conda命令 镜像源配置 conda config --show channels //查看镜像源conda config --remove-key channels //删除添加源,恢复默认源#添加镜像源conda config --ad

推荐练习键盘盲打的网站

对于初学者来说,以下是一些推荐的在线打字练习网站: 打字侠:这是一个专业的在线打字练习平台,提供科学合理的课程设置和个性化学习计划,适合各个水平的用户。它还提供实时反馈和数据分析,帮助你提升打字速度和准确度。 dazidazi.com:这个网站提供了基础的打字练习,适合初学者从零开始学习打字。 Type.fun打字星球:提供了丰富的盲打课程和科学的打字课程设计,还有诗词歌赋、经典名著等多样

综合DHCP、ACL、NAT、Telnet和PPPoE进行网络设计练习

描述:企业内网和运营商网络如上图所示。 公网IP段:12.1.1.0/24。 内网IP段:192.168.1.0/24。 公网口PPPOE 拨号采用CHAP认证,用户名:admin 密码:Admin@123 财务PC 配置静态IP:192.168.1.8 R1使用模拟器中的AR201型号,作为交换路由一体机,下图的WAN口为E0/0/8口,可以在该接口下配置IP地址。 可以通过

JAVA学习-练习试用Java实现“删除有序数组中的重复项”

问题: 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 说明: 为什么返回数值是整数,但输出的答案是数组呢? 请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。 你可以想象内部操作如下