增量元素之间的最大差值——前缀dp

本文介绍如何通过暴力枚举和动态规划优化算法,解决一道简单题目。首先,暴力枚举结合边界最大值查找;接着,通过dp计算最小值,将时间复杂度降至O(n);最后,进一步优化空间复杂度,仅保留一个变量存储前一个最小值。
摘要由CSDN通过智能技术生成

题目

题目链接

题目链接

题目解析

法一:暴力枚举

此题由于是简单题,所以直接可以暴力枚举。暴力枚举的时候我们也可以考虑优化一下,比如外层枚举 n u m s [ i ] nums[i] nums[i] 的时候,内层直接找右边的最大值。

代码如下:

class Solution {
public:
    int maximumDifference(vector<int>& nums) {
        int n = nums.size();
        int ret = INT_MIN,mx;
        for(int i=0;i<n;i++){
            mx = *max_element(nums.begin()+i,nums.begin()+n);
            if(mx>nums[i])
                ret = max(ret,mx-nums[i]);
        }
        if(ret==INT_MIN)return -1;
        return ret;
    }
};

法二:dp优化

很明显,时间复杂度实际上还是 O ( n 2 ) O(n^2) O(n2) ,我们可以通过动态规划,提前求出 n u m s [ i ] nums[i] nums[i] 之前的最小值,然后我们就可以直接通过 n u m s [ i ] − d p m i n [ i − 1 ] nums[i]-dp_{min}[i-1] nums[i]dpmin[i1] 求得,此时时间复杂度被优化为了 O ( n ) O(n) O(n) ,但空间复杂度也上升到了 O ( n ) O(n) O(n)

代码如下:

class Solution {
public:
    const int maxn = 0x3f3f3f3f;
    int maximumDifference(vector<int>& nums) {
        //计算dp值
        int n = nums.size();
        int dp_min[n];
        memset(dp_min,0x3f,sizeof(dp_min));
        dp_min[0] = nums[0];
        int ret = INT_MIN;
        for(int i=1;i<n;i++) dp_min[i] = min(dp_min[i-1],nums[i]);
        //得出答案
        for(int i=0;i<n;i++){
            if(i>0&&nums[i]>dp_min[i-1]){
                ret = max(ret,nums[i]-dp_min[i-1]);
            }
        }
        if(ret==INT_MIN)return -1;
        return ret;
    }
};

法三:进一步优化空间复杂度

我们在 d p dp dp 求解的时候发现,我们转移的状态依赖并未跨维度,而仅仅只和上一个状态 d p [ i − 1 ] dp[i-1] dp[i1] 相关,所以我们实际上只需要一个变量来记录 n u m s [ i ] nums[i] nums[i] 前的最小值,故把所有的处理放到一个循环中实现即可。

代码如下:

class Solution {
public:
    int maximumDifference(vector<int>& nums) {
        int n = nums.size();
        int ret = -1, premin = nums[0];
        for (int i = 1; i < n; ++i) {
            if (nums[i] > premin) {
                ret = max(ret, nums[i] - premin);
            } else {
                premin = nums[i];
            }
        }
        return ret;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值