[Algorithm][动态规划][子序列问题][最长等差数列][等差数列划分 Ⅱ - 子序列]详细讲解

目录

  • 1.最长等差数列
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 2.[等差数列划分 II - 子序列]
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现


1.最长等差数列

1.题目链接

  • 最长等差数列

2.算法原理详解

  • 思路
    • 确定状态表示 -> dp[i]的含义

      • dp[i]:以i位置元素为结尾的所有的子序列中,最长的等差子序列的长度 -> 无法正确表示状态
        • 因为虽然可以找到i前一个值,但是却无法得知此时它前一个数是什么,此时的公差应该是多少,现在的规模是如何
      • dp[i][j]:以i位置以及j位置的元素为结尾的所有的子序列中,最长的等差子序列的长度(i < j)
    • 推导状态转移方程
      请添加图片描述

    • 优化:因为可能有重复元素,但是只取重复元素的最后一个元素,此时为了便于找到每个要找到的元素,有两个方案可供选择

      1. dp之前,将所有元素 + 下标绑定,放在哈希表中<元素, 下标数组>
        • 可行,但是效率仍不高,如果重复元素多的夸张,时间复杂度也可能逼近 O ( N ) O(N) O(N)
      2. 一边dp,一边保存离它最近的元素的下标<元素, 下标>
        • 既可以保证前面的元素都放进哈希表里
        • 也可以保证如果有重复元素,那么也被最近的一个元素覆盖掉了
    • 初始化:vector<vector<int>> dp(n, vector<int>(n, 2))

    • 确定填表顺序:有两种方案可供选择,但是第一种方案在本题中,并不可取

      1. 先固定最后一个数,再枚举倒数第二个数
        • 此方案不可行,因为如果后枚举倒数第二个数,那么相对它而言,它的最近元素就不固定了
      2. 先固定倒数第二个数,再枚举最后一个数
        • 此时相对第二个数,前面最近的元素在本轮中,就是固定的
    • 确定返回值:dp表里的最大值:ret < 3 ? 0 : ret


3.代码实现

int longestArithSeqLength(vector<int>& nums) 
{
    unordered_map<int, int> hash; // <nums[i], i>
    hash[nums[0]] = 0;

    int n = nums.size();
    vector<vector<int>> dp(n, vector<int>(n, 2));

    int ret = 2;
    for(int i = 1; i < n; i++) // 固定倒数第二个数
    {
        for(int j = i + 1; j < n; j++) // 枚举倒数第一个数
        {
            int a = 2 * nums[i] - nums[j];
            if(hash.count(a)) // 已经包含了判断 k < i
            {
                dp[i][j] = dp[hash[a]][i] + 1;
                ret = max(ret, dp[i][j]);
            }
        }

        hash[nums[i]] = i; // 存入当前下标,对应下一次的最近元素的下标
    }

    return ret;
}

2.[等差数列划分 II - 子序列]

1.题目链接

  • 等差数列划分 II - 子序列

2.算法原理详解

  • 思路
    • 确定状态表示 -> dp[i]的含义

      • dp[i]:以i位置的元素为结尾的所有子序列中,等差子序列的个数 -> 无法正确表示状态
        • 因为虽然可以找到i前一个值,但是却无法得知此时它前一个数是什么,此时的公差应该是多少,现在的规模是如何
      • dp[i][j]:以i位置的元素y以及j位置的元素为结尾的所有的子序列中,等差子序列的个数(i < j)
    • 推导状态转移方程

      • dp[i][j] += dp[k][i] + 1
        请添加图片描述
    • 优化:在dp之前,将<元素, 下标数组>绑定在一起,放进哈希表中

    • 初始化:vector<vector<int>> dp(n, vector<int>(n))

      • dp表里的值全部初始化为0
    • 确定填表顺序:固定倒数第一个数,枚举倒数第二个数

    • 确定返回值:dp表里面所有元素的和


3.代码实现

int numberOfArithmeticSlices(vector<int>& nums) 
{
    int n = nums.size();

    // 优化,<nums[i], vector<int> index()>
    unordered_map<long long, vector<int>> hash;
    for(int i = 0; i < n; i++)
    {
        hash[nums[i]].push_back(i);
    }

    vector<vector<int>> dp(n, vector<int>(n));

    int ret = 0;
    for(int j = 2; j < n; j++) // 固定第一个数
    {
        for(int i = 1; i < j; i++) // 枚举第二个数
        {
            long long a = (long long)2 * nums[i] - nums[j];
            if(hash.count(a))
            {
                for(auto& k : hash[a])
                {
                    if(k < i)
                    {
                        dp[i][j] += dp[k][i] + 1;
                    }
                }
            }

            ret += dp[i][j];
        }
    }

    return ret;
}

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

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

相关文章

碳微球是新型碳材料 在高科技领域应用价值极高

碳微球是新型碳材料 在高科技领域应用价值极高 碳微球是一种新型碳材料&#xff0c;由石墨片层在玻璃相的石墨结构间断分布而构成。   与碳纳米管、石墨烯等碳材料不同&#xff0c;碳微球具有独特的球形结构&#xff0c;这赋予了其高比表面、高堆积密度等特点及良好的导电性、…

PROFINET转CANOPEN(WL-ABC3033)连接台达伺服驱动器ASDA-B3

在工业自动化领域这片广阔天地中&#xff0c;通信协议的转换犹如一道横亘在工程师们面前的难题。特别是在将众多采用不同通信协议的设备汇聚一堂&#xff0c;共同协作完成任务的场景中&#xff0c;如何确保数据如丝般顺滑地穿梭于各个节点之间&#xff0c;确保每台设备都能心领…

Spring-DI入门案例

黑马程序员SSM框架教程 文章目录 一、DI入门案例思路分析二、实现步骤2.1 删除service中使用new形式创建的Dao对象2.2 提供以来对象对应的setter方法2.3 配置service与到之间的关系 一、DI入门案例思路分析 基于IoC管理bean&#xff08;上个案例已经实现&#xff09;service中…

进阶 RocketMQ - 消息存储-一张图掌握核心要点

看了很多遍源码整理的 一张图进阶 RocketMQ 图片&#xff0c;关于 RocketMQ 你只需要记住这张图&#xff01; 消息传递责任已移交至Broker&#xff0c;接下来如何处理&#xff1f;首先&#xff0c;我们需要确保消息的持久化&#xff0c;避免因宕机导致的数据丢失。那么&#xf…

生活旅游数据恢复:全国违章查询

【步骤一&#xff1a;备份数据】 在开始数据恢复之前&#xff0c;首先要做的是备份现有的数据。虽然这一步不直接涉及到数据恢复&#xff0c;但万一在恢复过程中出现问题&#xff0c;您还可以回滚到备份&#xff0c;以避免数据丢失。 打开全国违章查询app。在主界面上找到并点…

下载视频怎么转换MP4?wmv转换mp4,推荐这3种方法

在数字化时代&#xff0c;我们经常需要从网上下载各种视频&#xff0c;但有时候下载的视频并不是我们想要的格式&#xff0c;比如WMV。为了能在更多的设备上播放或进行编辑&#xff0c;我们可能需要将其转换为更通用的MP4格式。 那么&#xff0c;下载的视频如何转换成MP4呢&am…

上位机图像处理和嵌入式模块部署(f407 mcu内部flash编程)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 对于f407这样的mcu来说&#xff0c;有的时候我们需要对mcu内部的flash进行编程处理。有两种情况需要对flash进行编程&#xff0c;一种情况是可能一…

Simulink中使用powergui做FFT分析

快速傅里叶变换&#xff08;FFT&#xff09;能更快的将信号从时域转换到频域进行表示&#xff0c;在频谱图上&#xff0c;可以直观的观察到信号的不同频率的大小和性质。实现信号的降噪、滤波等效果。 Simulink中的powergui模块 powergui其实是电力系统的图形化用户接口&…

【最新鸿蒙应用开发】——使用axios完成手机号注册业务

使用Axios请求实现目标效果图&#xff1a; 短信验证码登录 校验图形验证码&#xff0c;校验通过 发送短信验证码到用户手机上&#xff0c;可通过在线 WebSocket查看&#xff1a;wss://guardian-api.itheima.net/verifyCode 根据 手机号 短信验证码 实现登录 更新图形验证码…

聊聊外贸开发信的相关问题

我想外贸开发开发信&#xff0c;这应该是一个老生常谈的话题&#xff0c;我也相信已经有不少博主写过关于开发信的内容。 我们也看到过很多的版本以及很多的技巧&#xff0c;但是我还是想要说上几句 &#xff0c;因为最近又有了一些新的想法&#xff0c;并且也见到了效果。 我…

操作系统笔记(1)进程相关

进程同步&#xff1a;多个相关进程在执行次序上进行协调&#xff0c;使并发执行的进程之间能按照一定的规则共享系统资源&#xff0c;并能很好的合作&#xff0c;从而使进程的执行具有可再现性。 进程之间可能存在互斥或者同步的关系。 互斥(间接相互制约关系)&#xff1a;访…

f4pga环境搭建教程

f4pga环境搭建教程 背景介绍 FOSS Flows For FPGA (F4PGA) project&#xff0c;是一套开源的FPGA工具链&#xff0c;号称the GCC of FPGAs&#xff0c;作用是将写的硬件描述语言&#xff08;verilog或VHDL&#xff09;转化为可以在FPGA上运行的可执行文件&#xff08;bit文件…

如何在Google App Engine上构建一个简单的应用

一位用户在学习使用Python语言进行Google App Engine开发时遇到了困难&#xff0c;他希望构建一个简单的应用程序&#xff0c;该应用程序可以从用户处获取姓名&#xff0c;将姓名写入数据存储&#xff0c;然后检索姓名并显示页面。他尝试了教程&#xff0c;但仍然不了解如何实现…

day2数据结构

双链表的插入 循环链表&#xff0c;判断循环链表是否为空 指向的是自己 仅设表尾指针的循环链表合并 代码举例 删除线性表的最小值&#xff0c;并由函数返回删除的值&#xff0c;空的位置&#xff0c;由最后一个元素填补&#xff0c;若表为空显示出错信息 &L 因为L会发生…

排序算法——快速排序(队列和栈实现非递归)

一、背景 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法&#xff0c;其基本思想为&#xff1a;任取待排序元素序列中的某元素作为基准值&#xff0c;按照该排序码将待排序集合分割成两子序列&#xff0c;左子序列中所有元素均小于基准值&#xff0c;右子序列中…

【php实战项目训练】——thinkPhP的登录与退出功能的实现,让登录退出畅通无阻

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

对新手友好的最简单方便的本地项目关联git远程仓库教程

对新手友好的最简单方便的本地项目关联git远程仓库教程 前置条件1.本地项目2.gitee上创建同名项目 关联操作1.在本地进行clone远程仓库操作2.把本地项目下的目录和文件都复制到这个克隆自git的项目文件夹里面3.查看文件状态和提交文件 在我们创建项目时&#xff0c;一般都是在本…

Java IO流的基本概念和使用,包括文件读写、序列化等

Java 输入输出&#xff08;IO&#xff09;系统提供了一套丰富的类和接口&#xff0c;用于处理文件读写、网络通信、数据序列化等各种数据操作。 IO 操作在任何编程语言中都扮演着重要角色&#xff0c;而 Java 的 IO 系统以其强大的灵活性和扩展性&#xff0c;成为开发者进行数…

【全开源】Fastflow工作流系统(FastAdmin+ThinkPHP)

&#x1f680;Fastflow工作流系统&#xff1a;高效协作&#xff0c;流程无忧​ 一款基于FastAdminThinkPHP开发的可视化工作流程审批插件&#xff0c;帮助用户基于企业业务模式和管理模式自行定义所需的各种流程应用&#xff0c;快速构建企业自身的流程管控体系&#xff0c;快…

短剧cps系统搭建开发,热门短剧推广分销系统。短剧分销是怎么操作的?

目录 前言&#xff1a; 二、短剧是怎么推广分销的&#xff1f; 二、 短剧分销系统有什么功能&#xff1f; 三、怎么搭建&#xff1f; 总结&#xff1a; 前言&#xff1a; 短剧分销项目目前的现状是多元化且充满活力的。随着短剧市场的快速发展和观众接受度的提高&#xff0…