LeetCode 1027——最长等差数列

阅读目录

    • 1. 题目
    • 2. 解题思路
    • 3. 代码实现

1. 题目

2. 解题思路

假设我们以 f[d][nums[i]]表示以 nums[i] 为结尾元素间距为 d 的等差数列的最大长度,那么,如果 nums[i]-d 也存在于 nums 数组中,则有:

f [ d ] [ n u m s [ i ] ] = f [ d ] [ n u m s [ i ] − d ] + 1 f[d][nums[i]]=f[d][nums[i]-d]+1 f[d][nums[i]]=f[d][nums[i]d]+1

否则, f [ d ] [ n u m s [ i ] ] = 1 f[d][nums[i]]=1 f[d][nums[i]]=1

d的取值范围为 [ − ( m a x − m i n ) , + ( m a x − m i n ) ] [-(max-min), +(max-min)] [(maxmin),+(maxmin)]。因为 nums[i]-d 要位于 nums[i] 的前面,所以,针对每一个 d ,我们初始化所有元素为 -1,然后从前往后开始遍历数组,根据上面的公式依次更新 f,其中最大的数值即为所求。

时间复杂度为 O ( d ∗ n u m s . s i z e ( ) ) O(d*nums.size()) O(dnums.size()),空间复杂度为 O ( n u m s . s i z e ( ) ) O(nums.size()) O(nums.size())

3. 代码实现

于是,我开始实现了第一版代码,完全就照着上面的解题思路来写。

class Solution {
public:
    int longestArithSeqLength(vector<int>& nums) {
        map<int, map<int, int> > dp;
        int max_value = 0;
        int min_value = 500;
        map<int, int> init_dp;
        for (size_t i = 0; i < nums.size(); ++i){
            max_value = max(max_value, nums[i]);
            min_value = min(min_value, nums[i]);
            init_dp[nums[i]] = -1;
        }
        int diff = max_value - min_value;
        int ret = 1;
        for (int d = -diff; d <= diff; ++d) {
            dp[d] = init_dp;
            dp[d][nums[0]] = 1;
            for (size_t i = 1; i < nums.size(); ++i) {
                if (dp[d].count(nums[i]-d) == 0) {
                    dp[d][nums[i]] = 1;
                    continue;
                }
                if (dp[d][nums[i]-d] != -1) {
                    dp[d][nums[i]] = dp[d][nums[i]-d] + 1;
                    ret = max(ret, dp[d][nums[i]]);
                }
                else {
                    dp[d][nums[i]] = 1;
                }
            }
        }
        
        return ret;
    }
};

很可惜,没有通过全部测试用例,超时了。

超出时间限制 53 / 65 个通过的测试用例

首先,这里的 dp就是充当哈希表的作用,不需要有序,没有必要用 map,我改成了 unordered_map后,通过了,但是执行用时和消耗内存都排在了末尾。

查看双层 for 循环,针对每一个d,我们其实可以都用同一个哈希表,所以代码作如下修改:

class Solution {
public:
    int longestArithSeqLength(vector<int>& nums) {
        int max_value = 0;
        int min_value = 500;
        unordered_map<int, int> init_dp;
        for (size_t i = 0; i < nums.size(); ++i){
            max_value = max(max_value, nums[i]);
            min_value = min(min_value, nums[i]);
            init_dp[nums[i]] = -1;
        }
        int diff = max_value - min_value;
        int ret = 1;
        for (int d = -diff; d <= diff; ++d) {
            unordered_map<int, int> dp = init_dp; // 这里每次都用同一个即可
            dp[nums[0]] = 1;
            for (size_t i = 1; i < nums.size(); ++i) {
                if (dp.count(nums[i]-d) == 0) {
                    dp[nums[i]] = 1;
                    continue;
                }
                if (dp[nums[i]-d] != -1) {
                    dp[nums[i]] = dp[nums[i]-d] + 1;
                    ret = max(ret, dp[nums[i]]);
                }
                else {
                    dp[nums[i]] = 1;
                }
            }
        }
        
        return ret;
    }
};

这样,速度和内存都有所提升,但提升得也非常有限。继续思考,题目中给出了 0 <= nums[i] <= 500 的限制条件,所以 n u m s [ i ] − d ∈ [ 0 , 500 ] nums[i]-d\in[0,500] nums[i]d[0,500],如果不在这个范围,肯定是无效的。所以,dp直接就可以用一个大小为 501 的数组来代替了,数组的下标就可以作为索引。

class Solution {
public:
    int longestArithSeqLength(vector<int>& nums) {
        int max_value = 0;
        int min_value = 500;
        for (size_t i = 0; i < nums.size(); ++i){
            max_value = max(max_value, nums[i]);
            min_value = min(min_value, nums[i]);
        }
        int diff = max_value - min_value;
        int ret = 1;
        for (int d = -diff; d <= diff; ++d) {
            vector<int> dp(501, -1);
            dp[nums[0]] = 1;
            for (size_t i = 1; i < nums.size(); ++i) {
                if (nums[i]-d < 0 || nums[i]-d > 500) {
                    dp[nums[i]] = 1;
                    continue;
                }
                if (dp[nums[i]-d] != -1) {
                    dp[nums[i]] = dp[nums[i]-d] + 1;
                    ret = max(ret, dp[nums[i]]);
                }
                else {
                    dp[nums[i]] = 1;
                }
            }
        }
        
        return ret;
    }
};

class Solution:
    def longestArithSeqLength(self, nums: List[int]) -> int:
        max_value = max(nums)
        min_value = min(nums)
        diff = max_value - min_value
        ret = 1
        for d in range(-diff, diff+1):
            dp = [-1] * 501
            dp[nums[0]] = 1
            for i in range(1, len(nums)):
                if 0 <= nums[i] - d <= 500:
                    dp[nums[i]] = max(dp[nums[i]-d]+1, 1)
                    ret = max(ret, dp[nums[i]])
                else:
                    dp[nums[i]] = 1
        return ret

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

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

相关文章

我们是如何测试人工智能的(八)包含大模型的企业级智能客服系统拆解与测试方法 -- 大模型 RAG

大模型的缺陷 -- 幻觉 接触过 GPT 这样的大模型产品的同学应该都知道大模型的强大之处&#xff0c; 很多人都应该调戏过 GPT&#xff0c;跟 GPT 聊很多的天。 作为一个面向大众的对话机器人&#xff0c;GPT 明显是鹤立鸡群&#xff0c;在世界范围内还没有看到有能跟 GPT 扳手腕…

武汉星起航引领跨境电商新纪元,助力卖家扬帆远航全球市场

在全球化的商业浪潮中&#xff0c;跨境电商行业异军突起&#xff0c;成为连接全球市场的重要纽带。亚马逊&#xff0c;作为全球零售电商的巨擘&#xff0c;为无数卖家提供了走向国际市场的广阔舞台。在这片充满机遇与挑战的蓝海中&#xff0c;武汉星起航电子商务有限公司以其独…

数字孪生技术在农业领域的应用

数字孪生技术在农业领域的应用&#xff0c;不仅能够提高农业生产的智能化水平&#xff0c;还能够促进农业资源的高效利用和农业环境的可持续发展。随着技术的不断进步和应用的深入&#xff0c;数字孪生将在农业领域发挥越来越重要的作用。数字孪生技术在农业领域的应用主要集中…

redis连接工具 windows版安装和redis命令

Redis是一个开源的使用C语言编写、支持网络、基于内存、可持久化的日志型、Key-Value数据库&#xff0c;并提供多种语言的API。 一、redis-windows版安装 在D盘符下新建个目录&#xff0c;把下载的绿色安装包放在该目录。 D:\Files Java\Redis-x64-3.2.100 解压到当前目录 …

跳蚱蜢(蓝桥杯)

文章目录 跳蚱蜢题目描述答案&#xff1a;20bfs 跳蚱蜢 题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 如下图所示&#xff1a; 有 9 只盘子&#xff0c;排成 1 个圆圈。 其中 8 只盘子内装着 8 只蚱蜢&#xff…

【单例测试】Mockito实战

目录 一、项目介绍二、业务代码2.1 导入依赖2.2 entity2.3 Dao2.4 业务代码 三、单元测试3.1 生成Test方法3.2 引入测试类3. 3 测试前准备3.4 测试3.4.1 name和phone参数校验3.4.2 测试数据库访问 3.4.3 数据库反例 总结 前面我们提到了《【单元测试】一文读懂java单元测试》 简…

【Redis教程0x04】详解Redis的4个高级数据类型

引言 在【Redis教程0x03】中&#xff0c;我们介绍了Redis中常用的5种基础数据类型&#xff0c;我们再来回顾一下它们的使用场景&#xff1a; String&#xff1a;存储对象、url、计数、分布式锁&#xff1b;List&#xff1a;消息队列&#xff1b;Hash&#xff1a;存储对象、购…

【Arxml专题】-29-使用Cantools将CAN Matrix Arxml自动生成C语言代码

目录 1 安装Python和Cantools 1.1 查看Python已安装的Package包 1.2 在Python中安装Cantools插件包 1.3 获取更多Cantools工具的更新动态 2 CAN Matrix Arxml自动生成C语言代码 2.1 批处理文件CAN_Matrix_Arxml_To_C.bat内容说明 2.2 CAN Matrix Arxml文件要求 2.3 如何…

JAVA 学习记录(1)

1.函数 (1)String.join(";", messages); ";" 表示分隔符&#xff0c;输出的结果&#xff1a; message; (2) Double.parseDouble(valueString); 它返回由字符串参数表示的双精度值。 (3) Double.valueOf((Float) value; float 类型的数值转化为double类…

UG NX二次开发(C#)-通过曲线组生成NURBS曲面

文章目录 1、前言2、UG NX中通过曲线组生成NURBS曲面的操作3、采用NXOpen C#方法的源代码1、前言 在UG NX中,曲线、曲面的操作使用比较多,对于创建NURBS曲面,可以通过曲线组来生成,本文以NXOpen C#的方法实现通过曲线组生成NURBS曲面的功能。对于UG NX二次开发感兴趣或者有…

-bash: ./1.sh: /bin/bash^M: bad interpreter: No such file or directory解决方法

1、执行脚本 ./1.sh时报如下错误 -bash: ./1.sh: /bin/bash^M: bad interpreter: No such file or directory 2、在Windows编辑的脚本导入Linux系统中&#xff0c;执行报错问题 yum install -y dos2unix 3、或者本地安装 rpm -ivh /mnt/Packages/dos...... 4、然…

springboot 中Aop注解切面实现收集日志与统计耗时2

一 Aop注解实现切面 1.1 工程结构 Before&#xff1a;前置通知, 在方法执行之前执行 Aroud&#xff1a;环绕通知, 围绕着方法执行 After&#xff1a;后置通知, 在方法执行之后执行 AfterReturning&#xff1a;返回通知, 在方法返回结果之后执行 AfterThrowing&#xff1a;异…

【软考高项】十七、项目管理概论之项目基本要素

1、项目基础 项目具备的一些要素&#xff1a; 1&#xff09;独特的产品、服务或成果 开展项目是为了通过可交付成果达成目标。 ◆ 目标 是所指向的结果、要取得的战略地位、要达到的目的、要获得的成果、要生产 的产品或者要提供的服务 ◆ 可交付成果 是指在某一过程、阶…

【STK】手把手教你利用STK进行导弹和反导仿真01 - STK/MMT模块安装部署

【STK】手把手教你利用STK进行导弹和反导仿真01 - STK/MMT模块安装部署 MMT模块与STK的版本是一一对应的,比如我现在手上的版本是MMT9的,那么我使用的STK的版本也必须是9版本的,如果你现在正在使用的是更高版本的STK,比如说10、11.2、11.6、12.2,那么该怎么办呢? 这个经本…

基于ssm的学生选课管理系统的设计与实现

一、功能介绍 管理员功能分析 1、管理员用户可以查询所有学生信息&#xff0c;也可以根据学生的学号、学院、专业、班级查询学生信息。可以修改学生的姓名、年龄、身份证号、性别、密码、专业、学院、班级&#xff0c;可以增加、删除学生 2、管理员用户可以查询所有教师信息&…

使用python实现布丰投针法

对于π的值&#xff0c;直到1946年的时候&#xff0c;人类才能将π的值精确计算到小数点后2037位&#xff0c;而现在的超级计算机的能力可以精确的计算到小数点后几十亿位&#xff0c;然而在计算机发明之前&#xff0c;还是使用这里的布丰投针法来计算π值&#xff0c;是最实用…

React antd中下拉框联动没有清除上一次选中的内容

bug&#xff1a; 第一次&#xff1a; 第二次&#xff1a; 解决方法&#xff1a; <Fotm.item> <SelectshowSearchplaceholder"请输入单位名称"filterOption{selectFilterOption}options{bmSelectOptions}onChange{handleDwmcChange}/></F…

非平坦地形下运动规划相关理论

1.SVD平面拟合方法 空间中的离散点得到拟合平面&#xff0c;其实就是一个最优化的过程。即求这些点到某个平面距离和最小的问题。我们知道一个先验消息&#xff0c;那就是该平面一定会过众散点的平均值。接着我们需要做的工作就是求这个平面的法向量。 根据协方差矩阵的SVD变换…

WiFi已连接却不可上网是什么原因?

很多使用wifi上网的用户都遇到过这样的问题,就是电脑已经连接了wifi,但就是上不了网。着到底是怎么回事呢?今天,极客狗带大家一起来找找WiFi已连接却不可上网是什么原因,并给出对应的解决方。 原因分析: 可能是ip地址冲突所导致,也有可能是宽带出先故障,不妨试试下面的…

MySQL:数据类型

文章目录 数据类型分类数值类型越界访问bit类型小数类型floatdecimal 字符串类型charvarchar 日期enum和set 数据类型分类 在MySQL数据库中&#xff0c;存在各种各样的数据类型&#xff1a; 针对于上述的这么多类型&#xff0c;本篇就对于这些类型的数据进行一一解释&#xff…