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

目录

一,最长等差子序列

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;

    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

功率整流器的作用是什么?SURS8340T3G车规级功率整流器的介绍

汽车级功率整流器是一种用于汽车电子系统的功率电子器件&#xff0c;用于将交流电转换为直流电以供电子设备使用。汽车级功率整流器需要具有高效率、高可靠性、高稳定性和高温度工作能力等特点。其中&#xff0c;SURS8340T3G 是一种常见的汽车级功率整流器。 SURS8340T3G 是一…

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

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

快速了解软件工程学概述(5种软件过程模型)

目录 1 、什么是软件&#xff1f;特点有哪些 &#xff1f; 2 、 软件危机 定义&#xff1a; 软件危机产生的原因 消除软件危机的方法 3 、软件工程 1.软件工程的介绍 &#xff08;1&#xff09;概念 &#xff08;2&#xff09;本质特征 (3)软件工程方法学&#xff08;方…

优思学院|如何在企业中实施降本增效策略,实现财务突破

在当今竞争激烈的商业环境中&#xff0c;企业降低成本并提高效益变得至关重要。本文将深入探讨如何降本增效&#xff0c;以及实施这些策略的方法。 提到降本增效或提升生产效率&#xff0c;第一个被提出来检讨的一定是直接部门。但是如果无视于日渐臃肿的间接部门&#xff0c;…

全程云OA SQL注入漏洞复现

0x01 产品简介 全程云OA为企业提供日常办公管理、公文管理、工作请示、汇报、档案、知识体系、预算控制等26个功能&#xff0c;超过100多个子模块。为企业内部提供高效、畅通的信息渠道&#xff0c;同时也能大力推动公司信息系统发展&#xff0c;提高企业的办公自动化程度和综合…

SAS Planet软件介绍与使用教程

软件情况 SAS Planet是一位俄罗斯爱好者创建的的开源应用&#xff0c;该应用可以浏览与下载主流网络地图&#xff0c;包括Google地图、Google地球、Bing地图、Esri 地图、Yandex地图等。 该软件是基于Pascal开发的应用&#xff0c;目前已在github上开源&#xff0c;并使用了GP…

哈希表、哈希冲突解决办法

文章目录 一、什么是哈希表&#xff1f;二、什么是哈希冲突&#xff1f;怎样解决&#xff1f;三、哈希表的大小为什么是质数&#xff1f;四、链表法五、开放地址法线性探测法平方探测法双哈希(Double Hashing) 六、哈希表满了怎么办&#xff1f;七、完美哈希八、一些使用哈希解…

Java抽象类和接口(2)

&#x1f435;本篇文章继续对接口相关知识进行讲解 一、排序 1.1 给一个对象数组排序&#xff1a; class Student {public String name;public int age;public Student(String name, int age) {this.name name;this.age age;}public String toString() {return "name:…

爆肝整理! Python 网络爬虫 + 数据分析 + 机器学习教程来了

前段时间&#xff0c;有小伙伴多次在后台留言询问 Python 爬虫教程的问题。经过这两个多月以来的收集与整理&#xff0c;汇集了多个高校以及公开课视频教程&#xff0c;包括 python 爬虫的入门、进阶与实践&#xff0c;共 9G 左右。爬虫作为机器学习语料库构建的主要方式&#…

Python中的sys模块详解

1. 简介 sys模块是Python标准库中的一个内置模块&#xff0c;提供了与Python解释器和运行环境相关的功能。它包含了一些与系统操作和交互相关的函数和变量&#xff0c;可以用于获取命令行参数、控制程序的执行、管理模块和包、处理异常等。 2. 常用函数和变量 2.1 命令行参数…

虹科Pico汽车示波器 | 汽车免拆检修 | 2016款东风悦达起亚K5车发动机怠速抖动严重、加速无力

一、故障现象 一辆2016款东风悦达起亚K5车&#xff0c;搭载G4FJ发动机&#xff0c;累计行驶里程约为8.2万km。该车发动机怠速抖动严重、加速无力&#xff0c;同时发动机故障灯异常点亮&#xff0c;为此在其他维修厂更换了所有点火线圈和火花塞&#xff0c;故障依旧&#xff0c;…

自驾游汽车托运是交智商税吗?

自驾游汽车托运是交智商税吗? 亲爱的小伙伴们 你们有没有遇到过这样的困扰&#xff1a; 自驾游时&#xff0c;车辆的运输问题让你头疼不已? 是选择自己驾驶还是托运呢? 今天&#xff0c;我就来给大家种草一下汽车托运的好处&#xff0c; 让你的自驾游之旅更加轻松愉快! 1️.…

idea spring initializr创建项目报错

闲来无事就想搞个项目练练手&#xff0c;没想到直接给我卡在项目创建上了&#xff0c;一个个问题最终迎刃而解。 1.上来就给我报了个maven的错 未解析的插件: ‘org.apache.maven.plugins:maven-resources-plugin:3.3.1’ 不慌&#xff0c;应该是maven的路径有问题&#xff0c…

本地Nginx服务搭建结合内网穿透实现多个Windows Web站点公网访问

文章目录 1. 下载windows版Nginx2. 配置Nginx3. 测试局域网访问4. cpolar内网穿透5. 测试公网访问6. 配置固定二级子域名7. 测试访问公网固定二级子域名 1. 下载windows版Nginx 进入官方网站(http://nginx.org/en/download.html)下载windows版的nginx 下载好后解压进入nginx目…

Flask WTForms 表单插件的使用

在Web应用中&#xff0c;表单处理是一个基本而常见的任务。Python的WTForms库通过提供表单的结构、验证和渲染等功能&#xff0c;简化了表单的处理流程。与此同时&#xff0c;Flask的扩展Flask-WTF更进一步地整合了WTForms&#xff0c;为开发者提供了更便捷、灵活的表单处理方式…

Linux(9):正规表示法与文件格式化处理

简单的说&#xff0c;正规表示法就是处理字符串的方法&#xff0c;他是以行为单位来进行字符串的处理行为&#xff0c;正规表示法透过一些特殊符号的辅助&#xff0c;可以让使用者轻易的达到【搜寻/删除/取代】某特定字符串的处理程序。 正规表示法基本上是一种【表示法】&…

【运营思维】美团面试题:如何把梳子卖给寺庙和尚?

Hello 小米的小伙伴们~ 欢迎来到小米的微信公众号&#xff01;今天小米要和大家分享一道美团运营面试题&#xff0c;题目可真是独特——“如何把梳子卖给寺庙和尚&#xff1f;”想必大家一定兴奋不已吧&#xff01; 首先&#xff0c;让我们理清思路&#xff0c;挑战这个看似不…

[学习笔记]IK分词器的学习

IK分词器有几种模式 # 测试分词器 POST /_analyze {"text":"黑马程序员学习java太棒了","analyzer": "standard" }# 测试分词器 POST /_analyze {"text":"黑马程序员学习java太棒了","analyzer": &quo…

最新AI创作系统ChatGPT系统运营源码+DALL-E3文生图+支持OpenAI-GPT全模型+国内AI全模型

一、AI创作系统 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI…

1评论收藏分享抖店不要再无脑铺货了!这个方法学会,7天流量就起飞~

这2023年都马上过完了&#xff0c;你还在上一堆链接到抖店吗&#xff1f;要知道这样无脑铺货是拿不到大流量的。 哪今天我给大家分享一个&#xff0c;比较适合新手操作&#xff0c;也能快速起流量出单的方法。 。首先你的店铺拿不到流量&#xff0c;一定要先查清楚你为什么拿…