122. 买卖股票的最佳时机 II

52 篇文章 0 订阅
15 篇文章 0 订阅

在这里插入图片描述
在这里插入图片描述
这道题绝对有中等难度了。可以用状态机dp来做,因为只和前一天的两个状态有关,所以可以状态压缩,压缩到常量级别。最后返回的是最后一天不持有股票的情况。因为最后一天买了就卖不出去,所以肯定不会买,如果之前有,那么最后一天必须要卖掉,所以最后一天肯定无股票。
贪心的应该是想不到的,只要当前这一天比前一天大,就让结果加上当前减去前一天的值

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        //只要后一天的比前一天的高就卖出
        //加入123,这样的,那么第一天买,第二天卖,赚了1元,然后再买再卖,赚了1元,一共2元。
        //和第一天买第三天卖结果一样
        //int res = 0;
        // for(int i = 1;i < prices.size(); ++i){
        //     if(prices[i] > prices[i-1]){
        //         res += (prices[i]-prices[i-1]);
        //     }
        // }

        //状态机dp,dp[i][0]和dp[i][1]的意思是第i天持有或者不持有股票手上的钱,注意是利润初始化,如果第一天就持有
        // vector<vector<int>> dp(prices.size(),vector<int>(2));
        // dp[0][0] = 0;
        // dp[0][1] = -prices[0];
        // //状态转移方程是如果今天是没有的,那么有可能前一天是有的然后今天卖掉的,也有可能前一天就是没有的
        // //如果今天是有的,可能前一天就是有的,或者前一天没有今天刚买
        // for(int i = 1; i < prices.size(); ++i){
        //     dp[i][0] = max(dp[i-1][0],dp[i-1][1]+prices[i]);
        //     dp[i][1] = max(dp[i-1][1],dp[i-1][0]-prices[i]);
        // }
        // //最后一定要不持有股票收益才最大,不买最后一天,或者最后一天卖掉
        // return dp[prices.size()-1][0];

        //状压dp,当前的状态只和前一天的两个状态有关
        int nhave = 0, have = -prices[0];
        for(int i = 1; i < prices.size(); ++i){
            int nhave1 = max(nhave,have+prices[i]);
            int have1 = max(have,nhave-prices[i]);
            nhave = nhave1;
            have = have1;
        }
        return nhave;
    }
};

贪心做做得了,用一个minn记录在碰到比自己大的之前的最小股票价格,碰到比自己大的,就让res加上两者之差,然后更新minn。如果碰不到比自己大的,证明都是小于等于自己的,就更新minn,毕竟minn越小赚得越多。

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        //贪心算法or状态机dp
        //可以卖了之后马上买当天
        //所以345,买3,然后4那天卖掉,然后买4,5那天卖掉和买3,5那天卖掉的结果一样
        //记录一个值,碰到比自己小的就更新,碰到比自己大的就买掉,然后买它,用当天的值来更新
        if(prices.size() == 0) return 0;
        int res = 0;
        int minn = prices[0];
        for(int i = 1; i < prices.size();++i){
            if(prices[i]>minn) {
                res+=prices[i]-minn;
                minn = prices[i];
            }
            minn = prices[i];
        }
        return res; 
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值