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 }

 

你可能感兴趣的:(time)