leetcode121 122 123 309买卖股票的最佳时机

121买卖股票的最佳时机I
https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/
动态规划
可以这样想,另取一个一样大小的数组,第i位记录第i天之前的最低价格cur_min,那么第i天卖出的收益就是第i天的价格num减去第i天之前的最低价cur_min,最后求新数组中所有元素的最大值即可(res)
f(i)表示第i天卖出的最大收益,num[i]表示第i天的价格
f(i) = num[i] - min(num[j])(j=0…i)
最终结果为max(f(i)) i=0…n

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int len = prices.size();
        if(len <= 1)
            return 0;
        int cur_min = prices[0];
        int res = 0;
        for(int num:prices)
        {
            cur_min = min(cur_min,num);  //最大收益一定是在某一个最低点买入的,因此要记录最低点
            res = max(res,num-cur_min);
        }
        return res;
        
    }
};

转自:
https://www.cnblogs.com/ganganloveu/p/3721162.html

详细分析:
https://www.cnblogs.com/willaty/p/8304914.html

122买卖股票的最佳时机II
https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/
贪心算法。可以多次买入卖出。最大利润就是求所有上升区段的和(每次股票盈利就可以卖出),即如果当前价格高于前一天的价格就给总结果里加上这个差值即可

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if(prices.size()==0 || prices.size()==1) return 0;
        int res = 0;
        for(int i=1;i<prices.size();++i)
        {
           int dif = prices[i]-prices[i-1]; //计算当前天和上一天的价格差值
            if(dif>0)  //如果大于0.加上
                res+=dif;
        }
        return res;       
    }
};

123买卖股票的最佳时机III
https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/

最直接的想法是将121的做法来两次,正一遍,反一遍,然后枚举中间点,求两边和的最大值。
参考:https://cloud.tencent.com/developer/article/1019199
正向求利润最大值forward,反向求利润最小值backward(求出最小后保存的时候需要取绝对值)(因为是从最后一天开始向前走的,当反向利润最小时,正向利润就最大),最后选中间点,分别求两边最大值加起来。

最简单的答案:https://cloud.tencent.com/developer/article/1019199
没看太懂

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int b1=INT_MIN,b2=INT_MIN;
        int s1=0,s2=0;
        for(int i=0;i<prices.size();i++)
        {
            b1=max(b1,-prices[i]);  //记录0-i的最小prices,相当于121中的cur_min
            s1=max(s1,b1+prices[i]); //第i天第一次卖出的最大利润,相当于121的res
            b2=max(b2,s1-prices[i]); //记录s1-i的最小prices,相当于cur_min2
            s2=max(s2,b2+prices[i]); //第i天第二次卖出的最大利润
        }
        return s2;
    }
};

309.最佳买卖股票时机含冷冻期
https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/
参考:
https://blog.csdn.net/zjuPeco/article/details/76468185
在这里插入图片描述
s0[i] = max(s0[i - 1], s2[i - 1])
s1[i] = max(s0[i - 1] - prices[i], s1[i - 1])
s2[i] = s1[i - 1] + prices[i]

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if (prices.size() <= 1)
            return 0;
        int s0 = 0;
        int s1 = -prices[0];
        int s2 = INT_MIN;
        for (int i = 1; i < prices.size(); i++){
            int pre0 = s0;
            int pre1 = s1;
            int pre2 = s2;  //pre0,1,2必须要有,因为s1中用到了pre0,s2用到了pre1
            s0 = max(pre0, pre2);
            s1 = max(pre0 - prices[i], pre1);
            s2 = pre1 + prices[i];
        }
        //最大利润不可能出现在buy而未sell的时候,所以不考虑s1
        return max(s0, s2);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值