LeetCode打卡练习之股票买卖的最佳时机3

32 篇文章 0 订阅

这道题目可以算是一道经典而又比较简单的动态规划问题了。

根据算法导论中的介绍,我们可以先来分析一下最优解的构成:两次交易没有重合区域,所以可以假定一个分界线,分界线左边的解是左边部分的最优解,而分界线右边部分的解也是最优解。求得这两个区域最优解的办法,就是股票买卖最佳时机1这道题目的解法。

所以说,为找到问题的答案,我们需要确定两个“最优”,先找到分界线的位置,再算出分界线左右两边的最优解。

如果我们暴力循环的话,这个解法就是可行的。时间复杂度为O(N^2),第一层循环遍历分界线所有的位置,第二层循环寻找最优解。这里注意,求解动态规划问题,这一步是不可跳过的!动态规划,本质上就是对于循环之类已有的解法进行优化,而不是凭空出来的解法。求解动态规划类问题,最好的思路就是不考虑时间复杂度,先找到一个可行的解法,再对它进行优化。

然后分析这个过程,直觉告诉我们这个解法存在重复计算,然后我们在脑海中推一下运算轨迹。这里再次注意,不要把求解子问题的方法看作一个已经封装好的函数。因为这个优化是对整个运算过程进行的。

我们分析一下求解子问题的方法,求得最优解需要前一个问题的最优解,这样我们如果我们要求出长为a的数组的最优解,我们就必须有长度为a-1的数组的最优解。 

这时我们观察右边,右边只要我们把计算“股票买卖最佳时间1”的解法反过来,变成必须先卖后买,就可以从小到大在O(n)时间之内填好这个表。(这对应时间的对称性???)

在纸上画出调用关系图来,就是差不多这个样子,我们接着分析储存中间结果的方法,显然,一个简单的数组就可以存储这些中间结果。我们用一个循环先把数组填满,然后再遍历一次数组找到i,就可以在线性时间复杂度O(n)之内求出问题的解。

 

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if(prices.size()==0) return 0;
        int rpros[prices.size()];
        int rmax=0;
        int min=prices[0];
        int rpro=0;
        int profit=0;
        for(int i=prices.size()-1;i>=0;i--){
            if(prices[i]>rmax)
                rmax=prices[i];
            else if(rmax-prices[i]>rpro) 
                rpro=rmax-prices[i];
            rpros[i]=rpro;
        }
        for(int i=0;i<prices.size();i++){
            if(prices[i]<min) min=prices[i];
            else if(prices[i]-min+rpros[i]>profit) 
            profit=prices[i]-min+rpros[i];
        }
        return profit;
    }
};

最后结果是87%,说明这个解法还是不错的,我不知道还有没有更优的解法,毕竟O(n)我感觉已经是这道题的极限了。 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值