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

z在是跟前面一篇买股票的相似,不过这道题最多只有两次买卖的机会。

看了提示用DP操作,但是想了很久还是没想出来。

后来看了网上的答案,自己分析了一下,完成了。惭愧。

DP 的式子如下:

total=max{buyin(0,i)+buyin(i,n)|0<i<n}。

就是分两段,至于在哪里分割先假设已知,然后就可以得到上面的式子。

在哪里分割可以用遍历来做,

这样就得到了总量。

非常经典的DP操作,可是我就没想出来。

其次,在buyin(0,i)中,从左往右遍历,是已知前面所有数据,所以要找到的是最低买入的点,然后实时现在i时候卖出的total。

    而在buyin(i,n)中,从右往左遍历遍历,是已知后面所有数据,所以要找的是最高卖出的点,然后实施更新现在i时候买入的total。

挺有意思的。


上代码

public class Best_time_to_buy_and_sell_stock_iii {
	 
	    public static int maxProfit(int[] prices) {
	        // Note: The Solution object is instantiated only once and is reused by each test case.
	        if (prices == null || prices.length == 0) {
	            return 0;
	        }
	        int n = prices.length;
	        int[] left = new int[n];
	        int[] right = new int[n];
	        int min = prices[0];//取min是因为买入,从左往右,只能先买入后卖出,所以是卖出数据变化,买入数据已知,所以要找出最低买入点
	        for (int i = 1; i < n; i++) {
	            left[i] = left[i - 1] > prices[i] - min ? left[i - 1] : prices[i] - min;
	            min = min < prices[i] ? min : prices[i];
	        }
	        int max = prices[n - 1];//取max是因为是卖出的,从右往左,买入的数据变化,<span style="font-family: Arial, Helvetica, sans-serif;">只能先买入后卖出,</span>卖出的数据已知,所以要找出最高的卖出点,根据变化的买入点判断最大total
	        for (int i = n - 2; i >= 0; i--) {
	          // right[i]=right[i+1]>prices[i]-max?right[i+1]:prices[i]-max;
	         //  max=prices[i]<max?prices[i]:max;
	           right[i] = right[i + 1] > max - prices[i] ? right[i + 1] : max - prices[i];
	           max = max > prices[i] ? max : prices[i];
	        }
	        int value = 0;
	        for (int i = 0; i < n; i++) {
	            value = value > left[i] + right[i] ? value : left[i] + right[i];
	        }
	        
	        return value;
	    }
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] s={1,99,98,198,2,99};
		System.out.println(maxProfit(s));
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值