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

题意:给定一个数组,第i个元素是第i天给定股票的价格。
设计一个算法来找到最大的利润。 您最多可以完成两个交易(2次买进2次卖出,2次交易不能有时间上的重叠)。


此题是前一题(前一题是最多1次交易)的升级版,我们可以参考前一题的思路来解决此题,附上连接:点击打开链接

我们知道了进行一次交易的解法,此题要求最多2次交易,那么我们最直接的想法就是将给定的数组分成2个数组,分别对这2个数组用上一题的解法求出最大利润值,二者相加即可得到我们想要的结果。

下面贴代码:

public class Solution {
    public int maxProfit(int[] prices) {
        int max = 0,max1 = 0;
        for(int i=1;i<prices.length-2;i++){   //将数组分成2部分,分别求最大利润
            if(i==1 || prices[i]>prices[i-1]){   //优化条件
               max1 = maxProfit1(prices,0,i+1)+maxProfit1(prices,i+1,prices.length);
               max = Math.max(max,max1);
            }
        }
        return Math.max(max,maxProfit1(prices,0,prices.length));  //考虑到1次交易可能比2次交易获得的利润更高
    }
    public int maxProfit1(int[] prices,int start,int end) {     //求数组从start到end中进行一次交易的最大利润
        if(end-start<=1) return 0;
        int[] dp = new int[end-start-1];
        dp[0] = prices[start+1]-prices[start];
        for(int i=1;i<dp.length;i++){
            if(dp[i-1]>=0) dp[i] = prices[start+i+1] - (prices[start+i]-dp[i-1]);
            else dp[i] = prices[start+i+1] - prices[start+i];
            //System.out.println(dp[i]);
        }
        int max = 0;
        for(int k:dp){
            if(k>max)
            max = k;
        }
        return max;
    }
}
相对于上一题,此题有几点需要 注意的地方:

1.将maxProfit1方法加以改进,增加了起始位置和终止位置2个参数,避免了每次划分数组时需要申请的额外空间。

2.增加了优化条件。(大家可以试一下,如果去除了优化条件,在LeetCode上运行是会TLE的。)下面解释一下:

在对数组进行划分时,如果prices[i]<=prices[i-1],那么

对于数组的第一部分,第i天出售的利润不会高于第i-1天

对于数组的第二部分,每次划分都会减少一个元素,利润是不可能增加的

故此种情况下,总利润不可能增加,我们不需要进行计算。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值