动态规划学习——等差子序列问题

目录

一,最长等差子序列

1.题目

2.题目接口

3.解题思路及其代码

二,等差序列的划分——子序列

1.题目

2.题目接口

3.解题思路及其代码


一,最长等差子序列

1.题目

给你一个整数数组 nums,返回 nums 中最长等差子序列的长度

回想一下,nums 的子序列是一个列表 nums[i1], nums[i2], ..., nums[ik] ,且 0 <= i1 < i2 < ... < ik <= nums.length - 1。并且如果 seq[i+1] - seq[i]0 <= i < seq.length - 1) 的值都相同,那么序列 seq 是等差的。

示例 1:

输入:nums = [3,6,9,12]
输出:4
解释: 
整个数组是公差为 3 的等差数列。

示例 2:

输入:nums = [9,4,7,2,10]
输出:3
解释:
最长的等差子序列是 [4,7,10]。

示例 3:

输入:nums = [20,1,15,3,10,5,8]
输出:4
解释:
最长的等差子序列是 [20,15,10,5]。

提示:

  • 2 <= nums.length <= 1000
  • 0 <= nums[i] <= 500

2.题目接口

class Solution {
public:int longestArithSeqLength(vector<int>& nums) {}
};

3.解题思路及其代码

1.状态转移方程:

      每次做动态规划问题时都要先找到状态转移方程。在这道题里面,我们要找的是最长的等差子序列,那我们的状态转移方程必须就是二维的,为什么呢?因为要找等差序列我们首先得找到差值,一个数是构成不了差的只有两个数才行。现在我规定:dp[i][j]表示以arr[i]和arr[j]为结尾的等差子序列的最大长度,差值为arr[j]-arr[i]。那我们的dp[i][j] = dp[k][i]+1。其中dp[k][i]也表示以arr[k],arr[i]为结尾的最长的等差子序列。

2.初始化:

因为:

所以这道题的子序列最小长度就应该为2。所以在初始化时可以初始化为2。

3.优化:

   这道题的优化点还是在与元素与下标数组或者下标的绑定。

   先来看第一种:

   元素与下标数组的绑定(要与下标数组绑定的原因在于元素的出现次数会重复)

操作如下:

vector<vector<int>>dp(n,vector<int>(n,2));unordered_map<int,vector<int>>hash;for(int i = 0;i<n;i++) hash[nums[i]].push_back(i);

但是在这道题里面如果按照上面的方式绑定的话,就会面临一个超时的问题。如下:

class Solution {
public:int longestArithSeqLength(vector<int>& nums) {int n = nums.size();int maxLenth = 2;vector<vector<int>>dp(n,vector<int>(n,2));unordered_map<int,vector<int>>hash;for(int i = 0;i<n;i++) hash[nums[i]].push_back(i);for(int j = 1;j<n;j++){for(int i = 0;i<j;i++){int num = 2*nums[i]-nums[j];for(auto e:hash[num]){if(e<i){dp[i][j] = dp[e][i]+1;}}maxLenth = max(maxLenth,dp[i][j]);}}return maxLenth;}
};

结果如下:

第二种优化方法:

元素与下标进行绑定。

前面说了,这道题里面是有重复元素的。如果直接初始化hash表就会出现下标覆盖的问题。所以在这里初始化下标就得来点技巧:

1.先初始化hash[nums[0]]  = 0;

 unordered_map<int,int>hash;hash[nums[0]] = 0;

2.先固定倒数第二个位置,遍历倒数第一个位置。(这样填表的目的就是为了在出现重复元素的时候能把离i最近的元素代入二不管其它元素)。

3.在遍历完i前面的元素以后才把hash[nums[i]]与i进行绑定。为什么呢?因为i下标肯定不是在i的前面的。并且,如果你在之前就将hash表就全部初始化了的话就会有覆盖问题。覆盖问题会导致在以i,j位置为结尾的等差序列本来是可以和前面的重复元素结成等差子序列的,但是因为下标覆盖问题导致我下标竟然比前面的元素小进而导致错误。

代码如下:

class Solution {
public:int longestArithSeqLength(vector<int>& nums) {int n = nums.size();int maxLenth = 2;vector<vector<int>>dp(n,vector<int>(n,2));unordered_map<int,int>hash;hash[nums[0]] = 0;for(int i = 1;i<n;i++){for(int j= i+1;j<n;j++){int num = 2*nums[i]-nums[j];if(hash.count(num)){dp[i][j] = dp[hash[num]][i]+1;}maxLenth = max(maxLenth,dp[i][j]);}hash[nums[i]] = i;}return maxLenth;}
};

结果:

二,等差序列的划分——子序列

1.题目

给你一个整数数组 nums ,返回 nums 中所有 等差子序列 的数目。

如果一个序列中 至少有三个元素 ,并且任意两个相邻元素之差相同,则称该序列为等差序列。

  • 例如,[1, 3, 5, 7, 9][7, 7, 7, 7] 和 [3, -1, -5, -9] 都是等差序列。
  • 再例如,[1, 1, 2, 5, 7] 不是等差序列。

数组中的子序列是从数组中删除一些元素(也可能不删除)得到的一个序列。

  • 例如,[2,5,10] 是 [1,2,1,2,4,1,5,10] 的一个子序列。

题目数据保证答案是一个 32-bit 整数。

示例 1:

输入:nums = [2,4,6,8,10]
输出:7
解释:所有的等差子序列为:
[2,4,6]
[4,6,8]
[6,8,10]
[2,4,6,8]
[4,6,8,10]
[2,4,6,8,10]
[2,6,10]

示例 2:

输入:nums = [7,7,7,7,7]
输出:16
解释:数组中的任意子序列都是等差子序列。

提示:

  • 1  <= nums.length <= 1000
  • -231 <= nums[i] <= 231 - 1

2.题目接口

 

class Solution {
public:int numberOfArithmeticSlices(vector<int>& nums) {}
};

3.解题思路及其代码

这道题的解题思路和前面的题目的思路差不多,只是dp[i][j]的所表示的意义不同了。这里的dp[i][j]表示以arr[i],arr[j]为结尾的子序列的个数。代码如下:

class Solution {
public:int numberOfArithmeticSlices(vector<int>& nums) {int n = nums.size();vector<vector<int>>dp(n,vector<int>(n));//这次表示的是以i,j下标为结尾的最大个数unordered_map<long long ,vector<long long>>hash;//使用long long是因为数据太大会溢出for(int i = 0;i<n;i++) hash[nums[i]].push_back(i);//元素+下标数组绑定是因为有重复元素。int count = 0;for(int j = 2;j<n;j++){for(int i= 1;i<j;i++){long long num =(long long) 2*nums[i] - (long long)nums[j];//使用long long是因为数据太大会溢出for(auto e:hash[num]){if(e<i){dp[i][j]+= dp[e][i]+1;//找前面的子序列的个数再加上自己这个新的。}else{break;//因为vector是尾插,所以出现重复元素时下标小的在前面。}}count+=dp[i][j];//统计所有等差子序列的个数}}return count;}
};

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

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

相关文章

NX二次开发UF_CURVE_create_arc_center_radius 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CURVE_create_arc_center_radius Defined in: uf_curve.h int UF_CURVE_create_arc_center_radius(tag_t center, double radius, tag_t help_point, UF_CURVE_limit_p_t limit_p…

SparkDesk知识库 + ChuanhuChatGPT前端 = 实现轻量化知识库问答

上一篇 讯飞星火知识库文档问答Web API的使用&#xff08;二&#xff09; 把星火知识库搞明白了&#xff1b; 然后又花了时间学习了一下gradio的一些基础内容: 在Gradio实现两个下拉框进行联动案例解读&#xff1a;change/click/input实践&#xff08;三&#xff09; 在Gradio实…

数据结构与算法编程题27

计算二叉树深度 #define _CRT_SECURE_NO_WARNINGS#include <iostream> using namespace std;typedef char ElemType; #define ERROR 0 #define OK 1 #define Maxsize 100 #define STR_SIZE 1024typedef struct BiTNode {ElemType data;BiTNode* lchild, * rchild; }BiTNo…

2023中学生古诗文阅读专辑(初中适用)使用和备考的几点建议

上周六的2023年第八届小学生古诗文大会复选结束后&#xff0c;很多孩子和家长大呼“太难了”&#xff0c;平时刷的题好像都没用&#xff0c;蓦然回首&#xff0c;发现很多题目都在主办方出版的《古诗文阅读专辑》上&#xff0c;只是考得非常的细。 所以&#xff0c;昨天有家长在…

计算机毕业设计|基于SpringBoot+MyBatis框架的电脑商城的设计与实现(系统概述与环境搭建)

计算机毕业设计|基于SpringBootMyBatis框架的电脑商城的设计与实现&#xff08;系统概述与环境搭建&#xff09; 该项目分析着重于设计和实现基于SpringBootMyBatis框架的电脑商城。首先&#xff0c;通过深入分析项目所需数据&#xff0c;包括用户、商品、商品类别、收藏、订单…

基于C#实现十字链表

上一篇我们看了矩阵的顺序存储&#xff0c;这篇我们再看看一种链式存储方法“十字链表”&#xff0c;当然目的都是一样&#xff0c;压缩空间。 一、概念 既然要用链表节点来模拟矩阵中的非零元素&#xff0c;肯定需要如下 5 个元素(row,col,val,down,right)&#xff0c;其中&…

初识数据结构

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 熬过了我们不想要的生活&#xf…

麒麟V10服务器搭建FTP服务

概念 1.1介绍 FTP&#xff1a;File transfer protocol 文件传输协议 1.2原理 默认采用被动模式 被动模式FTP 为了解决服务器发起到客户的连接的问题&#xff0c;人们开发了一种不同的FTP连接方式。这就是所谓的被 动方式&#xff0c;或者叫做PASV&#xff0c;当客户端通…

Vue路由器(详细教程)

路由&#xff1a; 1.理解&#xff1a;一个路由(route)就是一组映射关系&#xff08;key-value)&#xff0c;多个路由需要路由器&#xff08;router&#xff09;进行管理。 2.前端路由&#xff1a;key是路径&#xff0c;value是组件。 1、先安装vue-router路由 npm i vue-route…

车载通信架构 —— 传统车内通信网络LIN总线(低成本覆盖低速场景)

车载通信架构 —— 传统车内通信网络LIN总线(低成本覆盖低速场景) 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是…

redisserver一闪而过 redis闪退解决版本

1.进入Redis根目录 2.输入redis-server 或 redis-server.exe redis.windows.conf 启动redis命令&#xff0c;看是否成功。 执 一闪而过的问题 可能是因为已启动或者其他问题&#xff0c;需要重启 先输入redis-cli.exe再输入shutdown再输入redis-server.exe redis.windows.c…

扩散模型实战(十二):使用调度器DDIM反转来优化图像编辑

推荐阅读列表&#xff1a; 扩散模型实战&#xff08;一&#xff09;&#xff1a;基本原理介绍 扩散模型实战&#xff08;二&#xff09;&#xff1a;扩散模型的发展 扩散模型实战&#xff08;三&#xff09;&#xff1a;扩散模型的应用 扩散模型实战&#xff08;四&#xff…

计算机毕业设计|基于SpringBoot+MyBatis框架的电脑商城的设计与实现(用户上传头像+用户收货管理)

计算机毕业设计|基于SpringBootMyBatis框架的电脑商城的设计与实现&#xff08;用户上传头像&#xff09; 该项目分析着重于设计和实现基于SpringBootMyBatis框架的电脑商城。首先&#xff0c;通过深入分析项目所需数据&#xff0c;包括用户、商品、商品类别、收藏、订单、购物…

NX二次开发UF_CURVE_ask_parameterization 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CURVE_ask_parameterization Defined in: uf_curve.h int UF_CURVE_ask_parameterization(tag_t object, double param_range [ 2 ] , int * periodicity ) overview 概述 Retu…

国产Ai大模型和chtgpt3.5的比较

下面是针对国产大模型&#xff0c;腾讯混元&#xff0c;百度文心一言&#xff0c;阿里通义千问和chatgpt的比较&#xff0c;最基础的对一篇文章的单词书进行统计&#xff0c;只有文心一言和chatgpt回答差不多&#xff0c;阿里和腾讯差太多了

深度学习中的注意力机制:原理、应用与实践

深度学习中的注意力机制&#xff1a;原理、应用与实践 摘要&#xff1a; 本文将深入探讨深度学习中的注意力机制&#xff0c;包括其原理、应用领域和实践方法。我们将通过详细的解析和代码示例&#xff0c;帮助读者更好地理解和应用注意力机制&#xff0c;从而提升深度学习模…

Vue快速实践总结 · 下篇

文章目录 组件间通信方式父 --> 子通信props插槽 子 --> 父通信&#xff08;自定义事件&#xff09;任意组件通信全局事件总线消息订阅与发布 Vuex工作原理运行环境简单使用GettersmapState与mapGettersmapActions与mapMutations模块化 命名空间 VueRouter路由的作用与分…

OpenWrt Lan口上网设置

LAN口上网设置 连接上openwrt&#xff0c;我用的 倍控N5105&#xff0c;eth0&#xff0c;看到Openwrt的IP是10.0.0.1 在 网络 -> 网口配置 -> 设置好 WAN 口和 LAN 口 初次使用经常重置 openwrt 所以我设置的是 静态IP模式 - 网络 -> 防火墙 -> 常规设置 ->…

7.私信列表 + 发送列表

目录 1.私信列表 1.1 数据访问层 1.2 业务层 1.3 表现层 1.4 私信详情 2.发送列表 2.1 数据访问层 2.2 业务层 2.3 表现层 2.4 设置已读状态 1.私信列表 私信列表&#xff1a;查询当前用户的会话列表&#xff0c;每个会话只显示一条最新的私信、支持分页列表私信详情…

苹果cms搭建教程附带免费模板

准备工作: 一台服务器域名源码安装好NGINX+PHP7.0+MYSQL5.5 安装php7.0的扩展,fileinfo和 sg11,不安装网站会搭建失败。 两个扩展都全部安装好了之后 点击-服务-重载配置 这样我们的网站环境就配置完成啦 下载苹果cms 苹果cms程序github链接:选择mac10!下载即可 http…