zoukankan      html  css  js  c++  java
  • [LeetCode] 1027. Longest Arithmetic Subsequence 最长的等差数列


    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:

    Input: A = [3,6,9,12]
    Output: 4
    Explanation:
    The whole array is an arithmetic sequence with steps of length = 3.
    

    Example 2:

    Input: A = [9,4,7,2,10]
    Output: 3
    Explanation:
    The longest arithmetic subsequence is [4,7,10].
    

    Example 3:

    Input: A = [20,1,15,3,10,5,8]
    Output: 4
    Explanation:
    The longest arithmetic subsequence is [20,15,10,5].
    

    Constraints:

    • 2 <= A.length <= 1000
    • 0 <= A[i] <= 500

    这道题给了一个数组,让找最长的等差数列的长度,暴力搜索的时间复杂度太大,这里就不考虑了。像这种玩数组,求极值的题,刷题老司机们应该很容易就反应出应该用动态规划 Dynamic Programming 来做,首先来考虑如何定义 DP 数组,最直接的就是用一个一维数组,其中 dp[i] 表示区间 [0, i] 中的最长等差数列的长度,但是这样定义的话,很难找出状态转移方程。因为有些隐藏信息被我们忽略了,就是等差数列的相等的差值,不同的等差数列的差值可以是不同的,所以不包括这个信息的话将很难更新 dp 值。所以这里就需要一个二维数组,dp[i][j] 表示在区间 [0, i] 中的差值为j的最长等差数列的长度减1,这里减1是因为起始的数字并没有被算进去,不过不要紧,最后再加回来就行了。还有一个需要注意的地方,由于等差数列的差值有可能是负数,而数组的下标不能是负数,所以需要处理一下,题目中限定了数组中的数字范围为0到 500 之间,所以差值的范围就是 -500 到 500 之间,可以给差值加上个 1000,这样差值范围就是 500 到 1500 了,二维 dp 数组的大小可以初始化为 nx2000。更新 dp 值的时候,先遍历一遍数组,对于每个遍历到的数字,再遍历一遍前面的所有数字,算出差值 diff,再加上 1000,然后此时的 dp[i][diff] 可以赋值为 dp[j][diff]+1,然后用这个新的 dp 值来更新结果 res,最后别忘了 res 加1后返回,参见代码如下:


    class Solution {
    public:
        int longestArithSeqLength(vector<int>& A) {
            int res = 0, n = A.size();
            vector<vector<int>> dp(n, vector<int>(2000));
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < i; ++j) {
                    int diff = A[i] - A[j] + 1000;
                    dp[i][diff] = dp[j][diff] + 1;
                    res = max(res, dp[i][diff]);
                }
            }
            return res + 1;
        }
    };
    

    Github 同步地址:

    https://github.com/grandyang/leetcode/issues/1027


    参考资料:

    https://leetcode.com/problems/longest-arithmetic-subsequence/

    https://leetcode.com/problems/longest-arithmetic-subsequence/discuss/274611/JavaC%2B%2BPython-DP


    LeetCode All in One 题目讲解汇总(持续更新中...)

  • 相关阅读:
    JavaSE—集合框架
    JavaSE——集合框架
    RocketMq 在Netty 下是如何进行消息封装传输
    SpringBoot 初始化流程以及各种常见第三方配置的源码实现
    Java 重要知识点,踩过的坑
    Mysql 知识储备以及InnoDB
    java 编程英语单词,语句
    PlantUML
    Rocketmq broker 消息仓库
    AutowiredAnnotationBeanPostProcessor 的一些思考
  • 原文地址:https://www.cnblogs.com/grandyang/p/14399899.html
Copyright © 2011-2022 走看看