LeetCode Best Time to Buy and Sell Stock III

这是好题,所谓的好题就是必须用优化的方法解,否则通不过。只能交易两次股票,本来想到第二题中的方法,找每个最小值最大值的差值,找两个最大的,仔细分析发现,这样的方法是错的,比如5,9,6,12,按上面的方法回提取两个最大差值,5和9,6和12,如果后面还有数,假设还是5,9,6,12,那么最大的利润值应该是两次5和12,也就是说不能选择每临近的最大值最小值的差值。接下来想到了二分法,从某一点划分开,左侧选最大利润(第一题的方法),右侧选最大利润,两侧的和最大时就是结果。恩,可以,提交结果时出现时间限制,想到了肯定可以优化,怎么优化,方法就是:左侧找两个值保存最小值的位置,最大值的位置,每增加一个数时和原来的最小值最大值判断,同方法一一样;右侧怎么优化呢?和左侧一样还是记录最小值和最大值的位置(所谓的位置其实是参与构成最大利润的位置),每当当前i到达最小位置时,重新调用函数去的最大最小位置,但是仅仅这样优化是不够用的,对于特殊的降序的例子,还会出现时间限制,进一步分析发现,当出现降序时,最小位置和最大位置相等时,反过来也成立,这样优化就好做了,一旦最小位置和最大位置相等,利润就为0,而且之后还是为0,不用调用函数了,问题就解决了。如下:

int oneMaxProfit02(vector<int> &prices,int start,int end,int &minpos,int &maxpos)
{
	int maxdiff=0;
	int minvaluepos = start;
	minpos = start;
	maxpos = start;
	if(start>=end)
		return 0;
	for (int i=start+1;i<=end;i++)
	{
		if (prices[i]>prices[minvaluepos])
		{
			if(prices[i]-prices[minvaluepos]>maxdiff)
			{
				maxdiff = prices[i]-prices[minvaluepos];
				maxpos = i;
				minpos = minvaluepos;
			}
		}
		else
		{
			minvaluepos = i;
			//minpos = i;
		}
	}
	//if(maxpos<minpos)
	//	maxpos = minpos;
	return maxdiff;
}
int maxProfit(vector<int> &prices) {
	if(prices.size()==0||prices.size()==1)
		return 0;
	if (prices.size()==2)
	{
		if(prices[1]>prices[0])
			return prices[1]-prices[0];
		else
			return 0;
	}
	int leftprofit,rightprofit;
	int maxprofit;
	if(prices[prices.size()-1] - prices[0] > 0)
		maxprofit = prices[prices.size()-1] - prices[0];
	else
		maxprofit = 0;
	int leftminpos=0,leftmaxpos=0;
	int rightminpos,rightmaxpos;
	leftprofit = 0;
	rightprofit = oneMaxProfit02(prices,1,prices.size()-1,rightminpos,rightmaxpos);
	//rightprofit = prices[rightmaxpos] - prices[rightminpos];
	if(rightprofit>maxprofit)
		maxprofit = rightprofit;
	for (int i=1;i<prices.size()-1;i++)
	{
		if (prices[i]>prices[leftminpos])
		{
			if(prices[i] - prices[leftminpos]>leftprofit)
			{
				leftmaxpos = i;
				leftprofit = prices[leftmaxpos] - prices[leftminpos];
			}
		}
		if(prices[i]<prices[leftminpos])
		{
			leftminpos = i;
		}
		if (i==rightminpos)
		{
			if(rightminpos==rightmaxpos)//only in case of reverse order,once this occurs,rightprofit always will be 0;
				rightprofit = 0;
			else
				rightprofit = oneMaxProfit02(prices,i+1,prices.size()-1,rightminpos,rightmaxpos);
			//rightprofit = prices[rightmaxpos] - prices[rightminpos];
		}
		if(leftprofit + rightprofit > maxprofit)
			maxprofit = leftprofit + rightprofit;
	}
	return maxprofit;
}
傻逼优快云什么时候让添加验证码了,第一遍没提交上,看草稿箱里自动保存的一点也不完整,重写了一堆,有的地方写错了编辑框里的东西撤销了恢复不会来,有他妈的重写了一遍,磨磨唧唧,什么时候发一遍技术博客这么费劲了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值