leetcode-增量元素之间的最大差值

「这是我参与2022首次更文挑战的第39天,活动详情查看:2022首次更文挑战」。

题目

给你一个下标从 0 开始的整数数组 nums ,该数组的大小为 n ,请你计算 nums[j] - nums[i] 能求得的 最大差值 ,其中 0 <= i < j < n 且 nums[i] < nums[j] 。
返回 最大差值 。如果不存在满足要求的 i 和 j ,返回 -1 。

示例 1:
输入:nums = [7,1,5,4]
输出:4
解释:最大差值出现在 i = 1 且 j = 2 时,nums[j] - nums[i] = 5 - 1 = 4 。
注意,尽管 i = 1 且 j = 0 时 ,nums[j] - nums[i] = 7 - 1 = 6 > 4 ,但 i > j 不满足题面要求,所以 6 不是有效的答案。

示例 2:
输入:nums = [9,4,3,2]
输出:-1
解释:不存在同时满足 i < j 和 nums[i] < nums[j] 这两个条件的 i, j 组合。

示例 3:
输入:nums = [1,5,2,10]
输出:9
解释:最大差值出现在 i = 0 且 j = 3 时,nums[j] - nums[i] = 10 - 1 = 9 。

思路

典型动态规划的题目,其实跟之前做的最长单调递增子序列这些是比较类似的,按照动态规划的方法来就好。

状态定义

定义一个一维数组dp,dp[k]的含义是,在nums[0]~nums[k]的子数组中,以nums[k]作为结束题目中的nums[j],能得到的最大差值。根据这个状态定义,ans = max(dp)

转移方程

定义了dp[k],我们来推导dp[k+1]: 根据状态定义,既然dp[k+1]作为被减数,要让差值最大,那么nums[i]必须取nums[0]~nums[k]中的最大值。在dp[k]中,nums[k]作为题目中的nums[j],那么显然,nums[i]一定是nums[0]~nums[k-1]的最小值。我们可以分2种情况:

  1. num[k] >= num[i],此时num[i]是nums[0]~nums[k]的最小值,dp[k+1] = dp[k] + nums[k+1] - nums[k]
  2. num[k] < num[i],此时num[k]是nums[0]~nums[k]的最小值,dp[k+1] = nums[k+1] - nums[k]

所以,整理上述2种情况可以得到:

dp[k] = max(dp[k-1] + nums[k+1] - nums[k], nums[k+1] - nums[k])
复制代码
边界条件

注意k必须满足k>=1,我们可以计算dp[1] = nums[1] - nums[0];然后后续dp[k]跟dp[k-1]有关,从小到大逐渐求解即可。

注意

题目中说,"如果不存在满足要求的 i 和 j ,返回 -1"。如果ans <= 0,那么说明不存在后续比前序打的数,需要返回-1。

Java版本代码

class Solution {
    public int maximumDifference(int[] nums) {
        int len = nums.length;
        int[] dp = new int[len];
        dp[1] = nums[1] - nums[0];
        int ans = dp[1];
        for (int i = 2; i < len; i++) {
            dp[i] = Integer.max(nums[i] - nums[i-1], nums[i] - nums[i-1] + dp[i-1]);
            ans = Integer.max(ans, dp[i]);
        }
        if (ans <= 0) {
            ans = -1;
        }
        return ans;
    }
}
复制代码

おすすめ

転載: juejin.im/post/7068997011252445215