前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【DP】1027. Longest Arithmetic Sequence

【DP】1027. Longest Arithmetic Sequence

作者头像
echobingo
发布2019-05-14 10:14:17
5430
发布2019-05-14 10:14:17
举报
问题描述:

Given an array A of integers, return the length of the longest arithmetic subsequence in A.

Recall that a subsequence of A is a list A[i_1], A[i_2], ..., A[i_k] with 0 <= i_1 < i_2 < ... < i_k <= A.length - 1, and that a sequence B is arithmetic if B[i+1] - B[i] are all the same value (for 0 <= i < B.length - 1).

Example 1:
代码语言:javascript
复制
Input: [3,6,9,12]
Output: 4
Explanation: 
The whole array is an arithmetic sequence with steps of length = 3.
Example 2:
代码语言:javascript
复制
Input: [9,4,7,2,10]
Output: 3
Explanation: 
The longest arithmetic subsequence is [4,7,10].
Example 3:
代码语言:javascript
复制
Input: [20,1,15,3,10,5,8]
Output: 4
Explanation: 
The longest arithmetic subsequence is [20,15,10,5].
Note:
代码语言:javascript
复制
2 <= A.length <= 2000
0 <= A[i] <= 10000
解题思路:

这是一道求最长等差子序列的动态规划题目。问题的关键在于记录每一个元素与之前所有元素的差值次数。 以 [9,4,7,2,10] 为例,对于数字7,前面的数中,9与它的差值为2,4与它的差值为-3,因此可以考虑用dict {差值: 次数}来记录7。对于数字10,当遍历10前面的数字时,遍历到7,差值是-3,因为-3在7的位置出现过,因此在10的位置处,差值为-3的次数就为2。

因此,我们可以对列表中的每一个数建立一个字典,数据结构为 dp = [dict() for _ in A](注意不要写成 dp = [dict()] * len(A),因为这样在每次修改 dp[i] 时,其他的dict()会同时修改,即这样的初始化字典数组的方法是传引用式的)。

对于 dp[i][j] = k,表示以 i 结尾的子序列,差为 j 时的最长子序列长度为 k。如上述例子,记录以7为结尾的子序列的差值和次数,7对应的字典应该是 {2: 1, -3:1},即 dp[2][2] = 1, dp[2][-3] = 1

对任何差值 x,dp[i][x] = 1 为初始状态。每次循环枚举 j < i,计算 x = A[j] − A[i],如果差值 x 在 dp[j] 元素中出现过,则转移方程为 dp[i][x] = dp[j][x] + 1

最后,返回 dp 中所有 N 个字典中的次数的最大值,+1 就是最后的结果(因为求的是等差子序列的长度,因此结果等于最大差值次数加1)。

Python实现:
代码语言:javascript
复制
class Solution:
    def longestArithSeqLength(self, A):
        dp = [dict() for _ in A]
        maxl = 0
        for i in range(1, len(A)):
            for j in range(0, i):
                sub = A[j] - A[i]
                if sub in dp[j].keys():
                    dp[i][sub] = dp[j][sub] + 1
                else:
                    dp[i][sub] = 1
                maxl = max(maxl, dp[i][sub])
        return maxl + 1

print(Solution().longestArithSeqLength([9,4,7,2,10]))  # 3
print(Solution().longestArithSeqLength([83,20,17,43,52,78])) # 2
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.04.30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题描述:
    • Example 1:
      • Example 2:
        • Example 3:
          • Note:
          • 解题思路:
            • Python实现:
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档