leetcode之Best Time to Buy and Sell Stock && II && III

Best Time to Buy and Sell Stock的原题如下:

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

If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.

上题是求最大利润,利用动态规划的思想,在遍历的过程中只需保留之前的最小值和最大利润两个值,如果当前节点减去之前的最小值的差比最大利润大,则更新最大利润,如果当前节点比之前的最小值小,则更新最小值,便利完成后即得到最大利润。

int maxProfit(vector<int> &prices) {
		if(prices.size() <= 1)
			return 0;
		int min = prices[0];
		int maxP = 0;
		for(int i = 1; i < prices.size(); i++){
			if(prices[i] - min > maxP)
				maxP = prices[i] - min;
			if(prices[i] < min)
				min = prices[i];
		}
		return maxP;
	}
Best Time to Buy and Sell Stock II 的原题如下:

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 as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

上一道题限制只能交易一次,而在这道题中没有限制交易次数,在此情况下只要有利可图便可成交,因为当天在卖出后还可以继续买当天的股票,例如1,2,4这三个数,交易两次的最大利润和交易一次的最大利润是相同的,所以,我们在编程实现时只需将当前节点与其前一个节点进行比较,如果差值大于零,则可成交一次,同样是遍历一次后得到最大利润,时间复杂度为O(n)。

int maxProfit(vector<int> &prices) {
		if(prices.size() <= 1)
			return 0;
		int maxP = 0;
		for(int i = 1; i < prices.size(); i++){
			if(prices[i] > prices[i - 1])
				maxP += prices[i] - prices[i - 1];
		}
		return maxP;
	}

Best Time to Buy and Sell Stock  III的原题如下:

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).

可能是发现了在次数没有限制的情况下并没有增加多少难度,所以此题限制最多交易两次,此时可以采用分而治之的思想,针对每个节点,将其分为节点左边的最大利润和节点右边的最大利润,在扫描一遍的情况下即可得出最大利润,此时,求左边节点和右边节点最大利润的问题变成第一题的一次交易的最大利润问题,所以总的时间复杂度是O(n*n),在leetcode上提交时出现超时错误。

int maxProfit(vector<int> &prices) {
		if(prices.size() <= 1)
			return 0;
		int maxLeft = 0,maxRight = 0,max = 0;
		for(int i = 2; i < prices.size(); i++){
			maxLeft = maxProfit(prices,0,i);
			maxRight = maxProfit(prices,i,prices.size() - 1);
			if(maxLeft + maxRight > max)
				max = maxLeft + maxRight;
		}
		return max;
	}
	int maxProfit(vector<int>prices,int left,int right){
		if(left >= right)
			return 0;
		int min = prices[left];
		int maxP = 0;
		for(int i = left + 1; i <= right; i++){
			if(prices[i] - min > maxP)
				maxP = prices[i] - min;
			if(prices[i] < min)
				min = prices[i];
		}
		return maxP;
	}
上述求解思路是没问题的,接下来就是对其进行优化的问题,仍采用动态规划的思想,此时可以借鉴腾讯2012年的校招题的做法: http://blog.csdn.net/momentforver/article/details/23266391,但不同的是,此题只需利用一个数组保存节点左边的最大利润,而因为在求解节点右边的最大利润后即可得出最大利润,所以没有必要对节点右边的最大利润进行保存。此时空间复杂度为O(n),需要扫描两遍数组,所以其时间复杂度为O(n)。

int maxProfit(vector<int> &prices) {
		int len = prices.size();
		if(len <= 1)
			return 0;
		vector<int>vLeft(len,0);		
		int maxP = 0,min = prices[0],max = prices[len - 1],maxProfit = 0;
		for(int i = 1; i < len; i++)   //求当前节点左边的最大利润
		{
			if(prices[i] - min > maxP){
				maxP = prices[i] - min;				
			}	
			if(prices[i] < min)
				min = prices[i];
			vLeft[i] = maxP;
		}
		maxP = 0;
		for(int i = len - 2; i >= 0; i--){   //求当前节点右边的最大利润,同时计算左右最大利润
			if(max - prices[i] > maxP)
				maxP = max - prices[i];			
			if(prices[i] > max)
				max = prices[i];			
			if(vLeft[i] + maxP >  maxProfit)
				maxProfit = vLeft[i] +maxP;
		}
		return maxProfit;
	}






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值