123. Best Time to Buy and Sell Stock III

leetcode 123

Say you have an array for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete at most two transactions.

Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).


题意:一个数组中的第i个元素表示在第i天的股票价格。你可以完成最多两次交易,设计一个算法找到最大收益。你必须在买入股票之前已经将股票卖出了。

解题思路1:分别计算在两个子序列0~i和i~n-1上的最大收益(子序列上只交易一次),遍历i=0~n-1,求的收益和的最大值即所求。在每个子序列上求最大收益值同121题。此方法的时间复杂度为O(n2),代码如下:

Submission Result: Time Limit Exceeded.

class Solution {
public:
    int maxProfit(vector<int>& prices) {
		if(prices.size()==2)
			return (prices[1]-prices[0])>0?prices[1]-prices[0]:0;
		int maxP=0;//记录最大收益
        for(int i=0;i<prices.size();i++)//将数组划分成0-i及i-n两个区间,分别求其收益最大值
		{
			int max1=subMaxProfit(prices,0,i);
			int max2=subMaxProfit(prices,i,prices.size()-1);
			if(maxP<max1+max2)
				maxP=max1+max2;
		}
		return maxP;
    }

	//数组prices中从start到end的最大收益
	int subMaxProfit(vector<int>& prices,int start,int end) {
		if(end-start<=0)
			return 0;
		int min=prices[start];//记录股票价格最小值
		int maxP=0;//记录遍历过程中的最大收益
		for(int i=start+1;i<=end;i++)
		{
			if(prices[i]-min>maxP)//当天卖出能收获更大收益,则更新maxP
				maxP=prices[i]-min;
			if(min>prices[i])//当天的股票价格比此前记录的股票价格的最小值还要小,则更新min
				min=prices[i];
		}
		return maxP;
	}
};
解题思路2:为了在线性的运算时间内,遍历原数组保存0~i子序列中的最大收益至数组preMax[]中。然后利用此数组,再次遍历原数组,计算i~n-1子序列中的最大收益并同时计算两个子序列收益和,求其最大值。代码如下:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
		if(prices.size()==0)
			return 0;
		int n=prices.size();
		vector<int> preMax(n,0);//数组中第i个元素用来保存0…i的子序列的最大收益,i=0,…,n-1
		int i;
		int maxP=0;//保存最大收益值
		int min=prices[0];//记录股票价格最小值
		int maxp=0;//记录遍历i时在此之前收益的最大值
		for(i=1;i<n;i++)
		{
			if(maxp<prices[i]-min)//如果以当天卖出股票收益更大,则更新maxp及preMax[i]
			{
				preMax[i]=prices[i]-min;
				maxp=preMax[i];
			}
			else//否则preMax[i]为在此之前记录的收益最大值
				preMax[i]=maxp;
			if(min>prices[i])//更新股票价格的最小值
				min=prices[i];
		}
		int max=prices[n-1];//记录股票价格的最大值
		maxp=0;
		for(i=n-2;i>=0;i--)
		{
			if(maxp<max-prices[i])//以当天i买入股票以i+1…n-1的某一天股票价格最大值时卖出,收益更大,则更新maxp及posMax[i]
				maxp=max-prices[i];
			if(max<prices[i])
				max=prices[i];
			if(maxP<maxp+preMax[i])//两个子序列为0…i和i…n-1时总收益更大则更新
				maxP=maxp+preMax[i];
		}
		return maxP;
	}
};


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值