Best Time to Buy and Sell Stock II

解法一:动态规划第一版

主要思想是填profit数组,profit [ i ]表示在第i天的最大的利润为多少,如果第i天没有卖出情况,则与profit[ i -1 ]相同,否则要找出自所有可能的上一个卖出日以来,最大的利润,当上一个卖出日为j时,日i的利润表示为profit [ i ] + prices[ i - 1 ] + dp[ j ][ i ](注意prices下标从0开始,所以要减一,其中dp[ j ][ i ]表示从日j到日i的最小价格,是在之前的循环中算出来的)

但由于dp记录的最小价格数组占用了O(n^2)的额外空间,所以会MLE,优化见下一个解法

class Solution {
public:
    int maxProfit(vector<int> &prices) {
        int n=prices.size();
        if(n<2)
        {
            return 0;
        }
        vector<vector<int> > dp(n+1,vector<int>(n+1,0));
        //i stands for selling time
        for(int i=1;i<=n;++i)
        {
            //j stands for buying time
            for(int j=1;j<=i;++j)
            {
                //dp[j][i] stands for start from day j,until selling day(day i),the lowest price
                //careful prices index need to minus one
                if((i-1)>=j)
                {
                    dp[j][i]=dp[j][i-1]>prices[i-1]?prices[i-1]:dp[j][i-1];
                }
                else
                {
                    dp[j][i]=prices[i-1];
                }
            }
        }
		vector<int > profit(n+1,0);
		for(int i=2;i<=n;++i)
		{
			profit[i]=profit[i-1];
			for(int j=i-1;j>=1;--j)
			{
				int tmp=profit[j]+(prices[i-1]-dp[j][i]);
				if(tmp>profit[i])
				{
					profit[i]=tmp;
				}
			}
		}
        return profit[n];
    }
};

解法二:动态规划第二版

class Solution {
public:
    int maxProfit(vector<int> &prices) {
        int n=prices.size();
        if(n<2)
        {
            return 0;
        }
		vector<int > profit(n+1,0);
		for(int i=2;i<=n;++i)
		{
			profit[i]=profit[i-1];
			int min=prices[i-1];//record the min prices between j and i,
			for(int j=i-1;j>=1;--j)
			{
			    min=prices[j-1]>min?min:prices[j-1];
				int tmp=profit[j]+(prices[i-1]-min);
				if(tmp>profit[i])
				{
					profit[i]=tmp;
				}
			}
		}
        return profit[n];
    }
};


这一版主要是去除了用来记录区间最小值的dp二维数组,最小值可以通过一边计算,一边记录(代码中通min表示),=来实现

不会再有MLE,但是填profit数组的时间复杂度为O(n^2),在大数据时TLE了,需要更进一步的优化,见下一个解法


解法三:贪婪解法


class Solution {
public:
    int maxProfit(vector<int> &prices) {
        int n=prices.size();
        if(n<2)
        {
            return 0;
        }
        int res=0;
        int curVal=prices[0];
        for(int i=1;i<prices.size();++i)
        {
            if(prices[i]>curVal)
            {
                res+=(prices[i]-curVal);
                curVal=prices[i];
            }
            else
            {
                curVal=prices[i];
            }
        }
        return res;
    }
};
一般情况下如果没有贪婪解法的话,那么上一个动态规划的解法理应是最优的解法了,但此题确实存在贪婪解法,需要同胞们在做题之前好好分析清楚题目才能发现贪婪解法。

注意观察到2个现象:1.如果当前价格比前一日的价格低,那么前一日的价格是无效的,因为当后续日子中出现高价我们需要卖出股票时,以当前日的价格买入优于前一日的价格买入;2.如果当前日的价格比前一日的价格高,那么当前日可以卖出股票,买入日为前一日,因为如果当前日不卖出,攒着等待后续日子中出现更高的价格时卖出,得到的收益和当前日卖出,然后在当前日再买入,等到后续同样的日子卖出时收益是一样的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值