best-time-to-buy-and-sell-stock-iii

package com.ytx.array;
/**best-time-to-buy-and-sell-stock-iii
 *
 *     Say you have an array for which the i th 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).
 *
 * @author yuantian xin
 *     
 *     买卖股票第三部
 *  思路:有买卖股票2的经验,很容易想到直接顺序求两次的方法,但是直接求的时间复杂度是O(n2),所以可以用DP来优化
 *  设置left数组用来存储从0~i的最大利润,right数组用来存储从i~len-1的最大利润,最后通过一个for循环求max(left[i]+right[i])
 *  的最大值。对于每一个i值,left[i]表示从第0~i天第一次交易的最大利润值,right[i]表示从第i~n天的第二次交易的最大利润值,它们的和
 *  就是两次交易最大利润值,然后对每个i遍历,得到所有当中的最大值。因为两次交易不可以重叠(第一次交易卖出股票的那天可以进行
 *  第二次交易的买入股票),所以i其实是left和right的一个分界点。
 *  求left[i]我们是顺序求的,right[i]必须逆序求,这样才不会重叠。
 */
public class Best_time_to_buy_and_sell_stock_iii {
       
       public static int maxProfit(int[] prices) {
             
             int len = prices.length;
             
             int TotallMax = 0;
             
             int [] left = new int[len];//left数组用来存储从0~i的最大利润
             
             int [] right = new int[len];//right数组用来存储从i~len-1的最大利润
             
             
             //left顺序求最大值,dp思想,第一次交易
        left[0] = 0;
        int min_buy = prices[0];//第0~i天的最低买入价
        //left[i]求法是假设每天prices[i]为股票卖出日的价格,减去第0~i天的最低买入价得到最大值,再与left[i-1]比较取较大值
        //得到0~i天的最大利润值
             for(int i = 1; i < len; i++) {
                    min_buy = Math.min(min_buy, prices[i]);
                    left[i] = Math.max(left[i-1], prices[i]-min_buy);
             }
             
             //right逆序求最大值,第二次交易
             right[len-1] = 0;
             int max_sell = prices[len-1];//第i~len-1天的最高卖价
             //right[i]求法是假设每天的prices[i]为股票买进日的价格,求出第i~len-1天的最高卖出价,然后减去prices[i]得到最大值
             //再与right[i+1]相比较得到最大利润值,得到i~len-1天的最大利润值。
             for(int i = len-2; i >= 0; i--) {
                    max_sell = Math.max(max_sell, prices[i]);
                    right[i] = Math.max(right[i+1], max_sell-prices[i]);
             }
             
             //最后利用for循环得到两次交易和的最大值
             for(int i = 0; i < len; i++) {
                    TotallMax = Math.max(TotallMax, left[i]+right[i]);
             }
             
             
             return TotallMax;
       }
       public static void main(String[] args) {
             int [] stockPrices = {2,1,2,0,1};
             System.out.println(maxProfit(stockPrices));
       }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值