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

news2024/12/26 9:20:12

目录

一,最长等差子序列

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.coloradmin.cn/o/1258847.html

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

相关文章

M3u8视频文件怎么转换成MP4?一分钟解决!

大部分网课平台或者视频平台&#xff0c;都是基于m3u8格式的&#xff0c;这是因为m3u8格式本身的特点&#xff0c;既支持直播又支持点播。但是往往在其他平台或者设备上不兼容&#xff0c;就需要转成MP4格式&#xff0c;那么就像大家介绍3种好用的方法~ 方法一&#xff1a;使用…

详解HTTP协议(介绍--版本--工作过程--Fiddler 抓包显示--请求响应讲解)

目录 一.HTTP协议的介绍 1.1HTTP是什么&#xff1f; 1.2HTTP版本的演变 二.HTTP的工作过程 三.使用Fiddler抓包工具 3.1简单讲解Fiddler 3.2Fiddler工作的原理 3.3抓包结果分析 四.HTTP请求 4.1认识URL 4.2关于URL encode 4.3认识方法 4.3.1认识get和post 4.3.…

Fiddler弱网测试究竟该怎么做?

前言 使用Fiddler对手机App应用进行抓包&#xff0c;可以对App接口进行测试&#xff0c;也可以了解App传输中流量使用及请求响应情况&#xff0c;从而测试数据传输过程中流量使用的是否合理。 抓包过程&#xff1a; 1、Fiddler设置 1&#xff09;启动Fiddler->Tools->…

易点天下携AIGC创新成果KreadoAI亮相数贸会,解锁电商文化出海新可能

11月27日&#xff0c;第二届全球数字贸易博览会&#xff08;以下简称“数贸会”&#xff09;在浙江杭州完美落幕。作为出海营销领域最早一批布局AIGC战略的营销科技公司&#xff0c;易点天下受邀与来自全球800余家境内外数字贸易企业同台参展&#xff0c;并分享了旗下AIGC数字营…

拦截器使用详解

什么是拦截器? 拦截器是 Spring 框架提供的核⼼功能之⼀,主要⽤来拦截⽤户的请求, 在指定⽅法前后,根据业务需要执行预先设定的代码. 也就是说,允许开发⼈员提前预定义⼀些逻辑,在请求访问接口前/后执行.也可以在⽤户请求前阻止其进入接口执行 在拦截器当中&#xff0c;开发⼈…

广西铁塔发布ZETag定位服务,快递物流可视化将成趋势

在万亿的快递、物流红海市场中&#xff0c;可视化或将成为凸显差异化优势的一枚棋子。 11月17日&#xff0c;中国铁塔股份有限公司广西壮族自治区分公司&#xff08;以下简称“广西铁塔”&#xff09;在广西南宁召开“万物智联&#xff0c;贴‘芯’服务”物联网产品发布会&…

UE5富文本框学习(用途:A(名字)用刀(图片)击杀B(名字))

UE5-UMG教程-通用控件&#xff1a;多格式文本块&#xff08;RichTextBlock&#xff09;_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Pu4y1k7Z2/?p54&spm_id_frompageDriver 结果示例&#xff1a; 1.添加富文本框 2.添加文字样式库 点添加&#xff0c;更改每行行…

又又又重新刷题的第一天第一天第一天,这次目标是top100一定要刷完整至少一次两次吧:1/150:两数之和 2/150两数相加 3/150无重复字符的最长字串

题目1/150&#xff1a;两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重…

智慧工厂人员定位系统源码,融合位置物联网、GIS可视化等技术,实现对人员、物资精确定位管理

智慧工厂人员定位系统源码&#xff0c;UWB高精度定位系统源码 随着中国经济发展进入新常态&#xff0c;在资源和环境约束不断强化的背景下&#xff0c;创新驱动传统制造向智能制造转型升级&#xff0c;越发成为企业生存发展的关键。智能工厂作为实现智能制造的重要载体&#xf…

电商平台为什么要使用CDN加速?

随着电商零售市场的成熟&#xff0c;消费者越来越关注购物体验。电商零售平台的响应速度、稳定性和安全性&#xff0c;均可能直接影响用户购买欲和用户转化率。如何进一步提升用户体验成为电商零售企业在市场决胜的关键。 阿里云全站加速DCDN全球覆盖3200节点&#xff0c;在提…

【知网稳定检索】2024年应用经济学,管理科学与社会发展国际学术会议(AEMSS 2024)

2024年应用经济学&#xff0c;管理科学与社会发展国际学术会议&#xff08;AEMSS 2024&#xff09; 2024 International Conference on Applied Economics, Management Science and Social Development 2024年应用经济学&#xff0c;管理科学与社会发展国际学术会议&#xff…

无公网IP下,如何实现公网远程访问MongoDB文件数据库

文章目录 前言1. 安装数据库2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射2.3 测试随机公网地址远程连接 3. 配置固定TCP端口地址3.1 保留一个固定的公网TCP端口地址3.2 配置固定公网TCP端口地址3.3 测试固定地址公网远程访问 前言 MongoDB是一个基于分布式文件存储的数…

即时电商需求快速爆发,商城系统平台的安全性如何保障?

双11的狂欢刚刚落下帷幕&#xff0c;留下的不仅是消费者的购物满足和品牌商家的销售增长&#xff0c;更让我们看到了一个行业变革的微妙暗示。 回溯这场全民购物的盛大节日&#xff0c;我们不难发现&#xff0c;线下零售品牌在电商巨浪的冲击下&#xff0c;非但没有萎靡&#x…

2023年最值得推荐的数据分析平台,可能是它!

在知乎上&#xff0c;商业数据分析和可视化是热门话题&#xff0c;其中Tableau和PowerBI是讨论最多的两个工具。随着数据分析行业的快速发展&#xff0c;利用这两个工具生成可视化dashboard并进行数据探索分析确实高效便捷。 作为一名数据分析爱好者&#xff0c;我也经常尝试各…

点成案例 | 使用自动细胞计数仪进行酵母细胞计数

一、概述 酵母可用于基础研究、酿造和蒸馏以及食品生产等多种应用&#xff0c;这些应用的全过程都离不开准确的细胞计数和活力测定。事实证明&#xff0c;较小的尺寸和形态对于自动细胞计数仪来说是相当具有挑战性的&#xff0c;利用活体染色剂手动计数酵母的方法繁琐且容易出…

竞赛选题 题目:基于机器视觉opencv的手势检测 手势识别 算法 - 深度学习 卷积神经网络 opencv python

文章目录 1 简介2 传统机器视觉的手势检测2.1 轮廓检测法2.2 算法结果2.3 整体代码实现2.3.1 算法流程 3 深度学习方法做手势识别3.1 经典的卷积神经网络3.2 YOLO系列3.3 SSD3.4 实现步骤3.4.1 数据集3.4.2 图像预处理3.4.3 构建卷积神经网络结构3.4.4 实验训练过程及结果 3.5 …

微软Azure AI新增Phi、Jais等,40种新大模型

微软在官方宣布在Azure AI云开发平台中&#xff0c;新增了Falcon、Phi、Jais、Code Llama、CLIP、Whisper V3、Stable Diffusion等40个新模型&#xff0c;涵盖文本、图像、代码、语音等内容生成。 开发人员只需要通过API或SDK就能快速将模型集成在应用程序中&#xff0c;同时支…

十四、机器学习进阶知识:KNN分类算法

文章目录 1、KNN分类介绍2、KNN分类核心要素3、KNN分类实例1.1 鸢尾花分类1.2 手写数字识别 1、KNN分类介绍 分类是数据分析中非常重要的方法&#xff0c;是对己有数据进行学习,得到一个分类两数或构造出一个分类模型&#xff08;即通常所说的分类器(Classifier))。分类是使用…

亚马逊、eBay店铺如何提升销量转化?掌握测评自养号的技巧

跨境电商随着互联网和物流技术的迅速发展&#xff0c;消费者可以更轻松地借助跨境电商平台在全球范围内进行购物&#xff0c;而提到跨境电商&#xff0c;亚马逊平台是不可忽视。 在竞争激烈的亚马逊市场中&#xff0c;提升销量转化率是每个卖家都追求的目标&#xff0c;高转化…

电源模块测试系统有什么优势?如何助力电源模块高温测试?

可靠性测试是电源模块测试的重要项目之一&#xff0c;以检测电源模块的、质量性能以及长期使用的稳定性。高温操作测试是可靠性测试的常用方法之一&#xff0c;通过电源模块测试系统模拟实际高温工作环境&#xff0c;来检测其工作状态是否正常。 电源模块高温测试方法 电源高温…