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

和前两道题比起来的话,这道题最难了,因为限制了交易次数。
解决问题的途径我想出来的是:既然最多只能完成两笔交易,而且交易之间没有重叠,那么就divide and conquer。
设i从0到n-1,那么针对每一个i,看看在prices的子序列[0,...,i][i,...,n-1]上分别取得的最大利润(第一题)即可。
这样初步一算,时间复杂度是O(n2)。


改进:
改进的方法就是动态规划了,那就是第一步扫描,先计算出子序列[0,...,i]中的最大利润,用一个数组保存下来,那么时间是O(n)。
第二步是逆向扫描,计算子序列[i,...,n-1]上的最大利润,这一步同时就能结合上一步的结果计算最终的最大利润了,这一步也是O(n)。
所以最后算法的复杂度就是O(n)的。

 1 public class Solution {
 2     public int maxProfit(int[] prices) {
 3         // Start typing your Java solution below
 4         // DO NOT write main() function
 5         int len = prices.length;
 6         if(len < 2) return 0;
 7         int minBeforeK[] = new int[len];
 8         for(int i = 1; i < len; i ++){
 9             if(i == 1) minBeforeK[i] = prices[0];
10             else minBeforeK[i] = Math.min(minBeforeK[i - 1], prices[i - 1]);
11         }
12         int bestValueBeforeK[] = new int[len];
13         for(int i = 2; i < len; i ++){
14             if(i == 2) bestValueBeforeK[i] = prices[1] - prices[0] > 0 ? prices[1] - prices[0] : 0;
15             else bestValueBeforeK[i] = Math.max(prices[i - 1] - minBeforeK[i - 1], bestValueBeforeK[i - 1]);
16         }
17         int maxAfterK[] = new int[len];
18         maxAfterK[len - 1] = prices[len - 1];
19         for(int i = len - 2; i >= 0; i --){
20             if(prices[i] > maxAfterK[i + 1]) maxAfterK[i] = prices[i];
21             else maxAfterK[i] = maxAfterK[i + 1];
22         }
23         int max = 0;
24         for(int i = 0; i < len; i ++){
25             int cur = bestValueBeforeK[i] + maxAfterK[i] - prices[i];
26             max = max > cur ? max : cur;
27         }
28         return max;
29     }
30 }
原文地址:https://www.cnblogs.com/reynold-lei/p/3442572.html