LeetCode "Best Time to Buy and Sell Stock with Cooldown" !

本文详细介绍了如何通过优化动态规划方法解决股票买卖问题,包括两种不同的解决方案:一种为O(n^2)复杂度的朴素方法,另一种为更高效的O(n)复杂度的智能动态规划设计。文中通过实例代码和链接解释了如何使用滚动数组优化,减少空间复杂度并提高效率。

Very good DP one.

First I figured out a O(n^2) solution:

class Solution 
{
public:
    int maxProfit(vector<int>& prices) 
    {        
        int n = prices.size();
        if(!n) return 0;
        
        vector<int> dp(n);
        dp[0] = 0;
        for(int i = 1; i < n; i ++)
        {            
            int vn = dp[i-1]; // nothing
            
            // sell
            int vs = 0, sofarMin = INT_MAX;
            for(int j = i - 1; j >= 0; j --)
            {
                sofarMin = min(sofarMin, prices[j]);
                int localProfit = prices[i] - sofarMin;                
                
                int thisChoice = localProfit + (j >= 2? dp[j - 2] : 0);
                vs = max(vs, thisChoice);
            }            
            
            int v = max(vn, vs);
            dp[i] = max(dp[i], v);            
        }
        return dp.back();
    }
};

However by intuition, there must be a O(n) with smarter DP design. Yes!

class Solution 
{
public:
    int maxProfit(vector<int>& prices) 
    {        
        int n = prices.size();
        if(!n) return 0;
        
        vector<vector<int>> dp(n, vector<int>(3, 0)); // 0 buy, 1 rest, 2 sell
        dp[0][0] = -prices[0];        
        for(int i = 1; i < n; i ++)
        {    
            dp[i][0] = max(-prices[i] + dp[i-1][1] /*buy on last rest*/, dp[i-1][0] /* update best buy so far*/); // buy this            
            dp[i][2] = max( prices[i] + dp[i-1][0] /*sell on last buy*/, dp[i-1][2] /* update best sell so far*/); // sell this
            dp[i][1] = dp[i-1][2]; // rest this, somewhat greedy
        }
        
        return dp.back()[2]; // somewhat greedy
    }
};

As you can see, dp[][] vars are rolling. So we don't have to use DP array. 3 vars is enough :) - as this link shows:

https://leetcode.com/discuss/71354/share-my-thinking-process

转载于:https://www.cnblogs.com/tonix/p/4996490.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值