Leetcode 1218.最长定差子序列(Longest Arithmetic Subsequence of Given Difference)

Leetcode 1218.最长定差子序列

1 题目描述(Leetcode题目链接

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

输入:arr = [1,2,3,4], difference = 1
输出:4
解释:最长的等差子序列是 [1,2,3,4]
输入:arr = [1,3,5,7], difference = 1
输出:1
解释:最长的等差子序列是任意单个元素。
输入:arr = [1,5,7,8,5,3,4,2,1], difference = -2
输出:4
解释:最长的等差子序列是 [7,5,3,1]

提示:

  • 1 < = a r r . l e n g t h < = 1 0 5 1 <= arr.length <= 10^5 1<=arr.length<=105
  • − 1 0 4 < = a r r [ i ] , d i f f e r e n c e < = 1 0 4 -10^4 <= arr[i], difference <= 10^4 104<=arr[i],difference<=104

2 题解

  最开始就想定义 d p [ i ] dp[i] dp[i]表示以 a r r [ i ] arr[i] arr[i]结尾的最长等差子序列的值,然后用 d p [ i ] = m a x ( d p [ i ] , d p [ j ] + 1 ) dp[i]=max(dp[i], dp[j]+1) dp[i]=max(dp[i],dp[j]+1)的状态转移方程来做,可惜超时了,超时代码如下。

class Solution:
    def longestSubsequence(self, arr: List[int], difference: int) -> int:
        length = len(arr)
        dp = [1] * length
        for i in range(length):
            for j in range(i):
                if arr[i] - arr[j] == difference:
                    dp[i] = max(dp[i], dp[j] + 1)
        return max(dp)

使用字典来记录每个等差子序列的最后一个值:

  • key:等差子序列的最后一个值
  • value:key所对应的等差子序列的长度

那么我们遍历数组的时候,如果发现 a r r [ i ] − d i f f e r e n c e arr[i]-difference arr[i]difference在字典中,那么就令: d i c [ a r r [ i ] ] = d i c [ a r r [ i ] − d i f f e r e n c e ] + 1 dic[arr[i]] = dic[arr[i]-difference] + 1 dic[arr[i]]=dic[arr[i]difference]+1,同时更新一下最大值。

class Solution:
    def longestSubsequence(self, arr: List[int], difference: int) -> int:
        length = len(arr)
        retv = 1
        dic = {}
        for i in range(length):
            if arr[i] - difference in dic:
                dic[arr[i]] = dic[arr[i]-difference] + 1
                retv = max(retv, dic[arr[i]])
            else:
                dic[arr[i]] = 1
        return retv
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值