【刷题日记】最长定差子序列

news2024/9/21 11:03:00

给你一个整数数组 arr 和一个整数 difference,请你找出并返回 arr 中最长等差子序列的长度,该子序列中相邻元素之间的差等于 difference 。

子序列 是指在不改变其余元素顺序的情况下,通过删除一些元素或不删除任何元素而从 arr 派生出来的序列。

这道题,看了一眼,劈里啪啦一分钟写完,自信写完,时间超限,天杀的我就知道我不可能一分钟做出mid题!!

/**
 * @param {number[]} arr
 * @param {number} difference
 * @return {number}
 */
var longestSubsequence = function(arr, difference) {
    const n=arr.length;
    const dp=new Array(n+1).fill(1);
    let res=0;
    for(var i=0;i<n;i++){
        for(var j=0;j<i;j++){
            if(arr[i]-arr[j]==difference){
                dp[i]=Math.max(dp[i],dp[j]+1);
            }
        }
        if(res<dp[i])res=dp[i];
    }
    return res;
};

没关系,我们来理思路,这至少说明前面几道题我能做到看见即秒了。

其实我们思路基本上是对的,但是得利用一点巧思。

 看官方给的思路。

因为我们每次都在左侧找一个最近的等于arr【i】-d元素并取其对应dp值。

因此我们直接用dp【v】表示以v为结尾的最长的等差子序列的长度 

官方题解使用了动态规划的方法来解决这个问题,并且为了优化空间复杂度,采用了哈希表(在 JavaScript 中是

官方题解使用了动态规划的方法来解决这个问题,并且为了优化空间复杂度,采用了哈希表(在 JavaScript 中是 Map 对象)来存储中间结果。这种方法的关键是理解状态转移方程和如何利用哈希表来高效地实现这个方程。

在这个问题中,状态转移方程是 `dp[v] = dp[v-d] + 1`,意味着如果存在一个值为 `v-d` 的元素,那么以值为 `v` 的元素结尾的最长等差子序列的长度可以从以 `v-d` 结尾的最长等差子序列的长度推导出来,即在后者基础上加一。

解题步骤

1. 初始化:创建一个 Map 对象 `dp` 来存储每个值作为等差子序列末尾时的最长长度。同时,初始化一个变量 `ans` 来记录遍历过程中找到的最长等差子序列的长度。

2. 遍历数组:遍历给定数组 `arr` 中的每个元素 `v`。

3. 更新 DP 表:对于当前元素 `v`,查找 `dp` 中 `v-difference`(即 `v-d`)的值。如果找到了,说明存在一个等差子序列以 `v-d` 结尾,那么以 `v` 结尾的最长等差子序列的长度就是以 `v-d` 结尾的最长等差子序列的长度加一。如果没有找到,说明以 `v` 为结尾的等差子序列只包含 `v` 本身,其长度为1(这里通过 `(dp.get(v - difference) || 0) + 1` 实现,如果 `dp.get(v - difference)` 返回 `undefined`,则用 `0` 替代)。

为了更好理解 也可以替换成

if(dp.get(v - difference) ==undefined){
    dp.set(v,1)
}else{
    dp.set(v,dp.get(v - difference)+1)
}

4. 更新最大长度:每次更新 `dp[v]` 后,用 `dp.get(v)` 更新 `ans`,确保 `ans` 始终是遍历到目前为止找到的最长等差子序列的长度。

5. 返回结果:遍历结束后,`ans` 存储的就是整个数组的最长等差子序列的长度。

var longestSubsequence = function(arr, difference) {
    let ans = 0;
    const dp = new Map();
    for (const v of arr) {
        dp.set(v, (dp.get(v - difference) || 0) + 1);
        ans = Math.max(ans, dp.get(v));
    }
    return ans;
};

这段代码实现了上述逻辑:

- 使用 `for (const v of arr)` 遍历数组。
- 对每个元素 `v`,通过 `dp.set(v, (dp.get(v - difference) || 0) + 1);` 更新哈希表,这里 `dp.get(v - difference) || 0` 是获取以 `v-difference` 结尾的最长等差子序列的长度,如果不存在则返回0,然后加1表示将当前元素 `v` 加入到等差子序列中。
- 使用 `ans = Math.max(ans, dp.get(v));` 更新找到的最长等差子序列的长度。
- 最终返回 `ans` 作为结果。

如果想把过程写的更加清晰一点就:

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

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

相关文章

HDL Designer 2021.1 如何将默认编辑器修改为VsCode

第1步 安装Vscode 第2步 添加Vscode至HDL Designer 第3步 更改HDL Designer编译器 第4步 修改结束&#xff0c;在HDL Designer中双击block可使用Vscode编辑verilog

SpringBoot+Druid并开启监控页面

介绍 Druid 是一个开源的数据库连接池项目&#xff0c;由阿里巴巴集团开发并贡献给开源社区。它在Java领域中以其高性能、强大功能和易用性著称&#xff0c;是Java应用中广泛使用的数据库连接池组件之一。 Druid 的主要特点包括&#xff1a;   高性能与低延迟&#xff1a; Dr…

2月6日作业

1.现有无序序列数组为23,24,12,5,33,5347&#xff0c;请使用以下排序实现编程 函数1:请使用冒泡排序实现升序排序 函数2:请使用简单选择排序实现升序排序 函数3:请使用快速排序实现升序排序 函数4:请使用插入排序实现升序排序 #include<stdio.h> #include<string.h&…

我的QQ编程学习群

欢迎大家加入我的QQ编程学习群。 群号:950365002 群里面有许多的大学生大佬&#xff0c;有编程上的疑惑可以随时问&#xff0c;也可以聊一些休闲的东西。 热烈欢迎大家加入&#xff01;&#xff01; 上限:150人。

C++核心deque容器,stack容器,queue容器,list容器,set容器,pair ,map容器

3.deque容器 1.deque容器的基本概念 Vector容器是单向开口的连续内存空间&#xff0c;deque则是一种双向开口的连续线性空间。所谓的双向开口&#xff0c;意思是可以在头尾两端插入元素&#xff0c;但是在其头部操作效率奇差&#xff0c;无法被接受。 deque容器和vector容器最…

【C++第二阶段】空指针访问成员函数常成员函数常成员属性

你好你好&#xff01; 以下内容仅为当前认识&#xff0c;可能有不足之处&#xff0c;欢迎讨论&#xff01; 文章目录 空指针访问成员函数常成员函数&常成员属性 空指针访问成员函数 类对象类型的空指针可以访问成员函数&#xff0c;但是不能够访问带有成员属性的成员函数。…

Java基于微信小程序的医院核酸检测服务系统,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

arduino D1 中esp8266 没有ide的库

http://arduino.esp8266.com/stable/package_esp8266com_index.json https://arduino.esp8266.com/stable/package_esp8266com_index.json 这个是官网的包地址 拿到后复制到arduino ide中 然后在开发板管理器&#xff0c;搜索esp&#xff0c;搜出来后安装 去开发板选择 然后测…

俩种方法解决 VScode中 NPM 脚本消失,NPM 脚本未显示在资源管理器侧栏中

npm脚本是npm包管理器的一个功能&#xff0c;允许开发者在package.json文件中定义一系列命令脚本&#xff0c;用于执行各种开发任务。 今天打开准备运行的时候发现找不到NPM脚本了&#xff0c;左侧的一栏完全没有显示&#xff0c;在网上查阅了很多资料后总结出俩个方法可以用来…

前端基础复习(后端人员看前端知识)

企业级前端项目开发中&#xff0c;需要将前端开发所需要的工具、技术、流程、经验进行规范化和标准化&#xff0c;而不是零散的html、js、css文件堆叠在一起。 首先我们需配置前端的开发基础环境NodeJS&#xff0c;相当于后端人员java开发的JDK。然后搭建前端工程脚手架Vue-cl…

vue electron应用调exe程序

描述 用Python写了一个本地服务编译成exe程序&#xff0c;在electron程序启动后&#xff0c;自动执行exe程序 实现 1. 使用node的child_process模块可以执行windows执行&#xff0c;通过指令调exe程序 // electron/index.js var cp require("child_process"); /…

企业邮箱是什么?企业邮箱百科

本文将为大家讲解&#xff1a;1、企业邮箱的定义&#xff1b;2、企业邮箱的主要功能特点&#xff1b;3、企业邮箱如何选择和部署&#xff1b;4、企业邮箱的运营与维护&#xff1b;5、企业邮箱在实际工作中的应用与挑战&#xff1b;6、2024年最新五大企业邮箱盘点   下面提到的…

U盘显示空间小于实际U盘空间的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

IP地址如何保护网络安全

面对网络攻击时&#xff0c;仅依靠常态化的网络安全防御系统已捉襟见肘&#xff0c;如联合使用IP地址数据可以形成多元化的安全解决方案&#xff0c;全面监控网络活动&#xff0c;发现潜在威胁&#xff0c;制定有针对性的应对措施。 网络攻击追踪 当网站或应用遭受DDoS等网络攻…

【JS逆向五】逆向模拟某网站的生成的【jsonKey】值 仅供学习

逆向日期&#xff1a;2024.02.07 使用工具&#xff1a;Node.js 加密方法&#xff1a;AES 文章全程已做去敏处理&#xff01;&#xff01;&#xff01; 【需要做的可联系我】 可使用AES进行解密处理&#xff08;直接解密即可&#xff09;&#xff1a;在线AES加解密工具 1、打开…

Spring Batch 批处理框架适配达梦数据库,实现从文件批量读取写入数据库(完整教程)

效果展示(达梦数据库): 技术简介: Spring Batch 是一个基于 Spring 的批处理框架,用于开发和执行大规模、高性能、可靠的批处理应用程序。它提供了丰富的功能和组件,用于处理复杂的批处理任务,例如大数据ETL(Extract-Transform-Load)、数据清洗、数据迁移、报表生成…

StringBuilder类常用方法(Java)

StringBuilder类常用方法 StringBuilder 是 Java 中常用的字符串缓冲区类&#xff0c;适用于频繁修改字符串的场景。 1. append(): 将指定字符串、字符、布尔值或其他数据类型的表示追加到字符串缓冲区的末尾。 StringBuilder sb new StringBuilder("Hello"); sb.…

9.0 Zookeeper 节点特性

本章节介绍一下 zookeeper 的节点特性和简单使用场景&#xff0c;正是由于这些节点特性的存在使 zookeeper 开发出不同的场景应用。 1、同一级节点 key 名称是唯一的 实例&#xff1a; $ ls / $ create /runoob 2 已存在 /runoob 节点&#xff0c;再次创建会提示已经存在。 …

SDWAN组网一般会需要哪些设备

随着企业网络需求的不断增长和变化&#xff0c; SD-WAN作为一种先进的网络架构技术&#xff0c;需要一系列设备来构建有效的组网。以下是SD-WAN组网所需的一些关键设备清单&#xff1a; &#xff08;1&#xff09;SD-WAN路youqi&#xff1a; SD-WAN路youqi是SD-WAN网络的核心设…

【Spring Boot】第一篇 创建简单的Spring Boot项目

导航 一. 简介二. 创建简单的Spring Boot项目1. 工具选择和版本确定2. 创建步骤 三. 部署项目四. 测试验证 一. 简介 Spring Boot是一个用于构建独立的、生产级别的Spring应用程序的框架。它简化了Spring应用程序的创建和配置过程&#xff0c;同时提供了很多开箱即用的功能&am…