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).
思路:本人脑子比較笨,思路比較冷门,并且效率高。
时间复杂度最大为O(n^2),最小为为O(n),并不固定,空间复杂度为O(n)。时间复杂度为什么不固定,下文再说。注意如果是分为两次购买,则第一次卖出而第二次买入之间的时间内。股票必然下跌,否则就不须要分两次购买了。如果他第一次是从a天购入,第b天卖出;第二次购买是从第c天购入。
则从第b天至第c天之间至少股票价格下跌一次,甚至连续下跌,所以我们仅仅须要找sub[i]<0的地方断开。分两次购买试试。所以当股票价格2i天上升。第2i+1天下降,或着第2i天下降。第2i+1天上升时。时间复杂度度为O(n^2)
1.用一个数组sub[n-1]。(n为股票价格的天数)来存储当天与前一天股票的差价,即sub[i]=prices[i+1]-prices[i],从而将该题转化为一个或者两个最大子序列和的问题。
2.当股票从第2天到第m天一直下跌时。而第m+1天股票价格上涨,则将sub[0...m-1]置为0。当股票在k天上涨。而从从第k+1天到第n一直跌,则将sub[k+1....n]置为0(本步骤不过为了优化,非必须)
3.计算出仅仅购买一次的最大收益,与全部的当sub[i]<0时(这种i有可能不止一个),分两次购买的收益做比較。取最大值就可以。
版本号1。用数组,快一些
public class Solution { public int maxsum(int[] num,int start,int end) { int sum = 0; int max = Integer.MIN_VALUE; for (int i = start; i <=end; i++) { sum += num[i]; if (max < sum) { max = sum; } if (sum <= 0) { sum = 0; } } return max>>0?max:0; } public int maxProfit(int[] prices) { if (prices.length == 0 || prices.length == 1) return 0; int[] sub = new int[prices.length - 1]; boolean flag=false; for (int i = 0; i < sub.length; i++){ if(prices[i+1]-prices[i]>=0||flag){ flag=true; sub[i] = prices[i + 1] - prices[i]; }else{ sub[i]=0; } } for (int i = sub.length-1; 0 <= i; i--){ if(prices[i+1]-prices[i]<0){ sub[i] = 0; }else{ break; } } int result=maxsum(sub,0,sub.length-1); for (int i=0;i<sub.length;i++){ if(sub[i]<0){ int temp=maxsum(sub,0,i-1)+maxsum(sub,i+1,sub.length-1); result=result>temp?result:temp; } } return result; } }
版本号2,使用ArrayList,当股票从一開始持续下跌,或着从某时间到结束一直下跌。则删除这些sub值。
import java.util.ArrayList; public class Solution { public int maxsum(ArrayList<Integer> num,int start,int end) { int sum = 0; int max = Integer.MIN_VALUE; for (int i = start; i <=end; i++) { sum += num.get(i); if (max < sum) max = sum; if (sum <= 0) sum = 0; } return max>0?max:0; } public int maxProfit(int[] prices) { if (prices.length==0||prices.length==1) return 0; ArrayList<Integer> sub = new ArrayList<Integer>(); boolean flag=false; for (int i = 0; i < prices.length-1; i++){ if(prices[i+1]-prices[i]>=0||flag){ flag=true; sub.add(prices[i + 1] - prices[i]); } } for (int i = prices.length-2; 0 <= i; i--){ if(!sub.isEmpty()&&prices[i+1]-prices[i]<0) sub.remove(sub.size()-1); else break; } if(sub.size()==0) return 0; int result=maxsum(sub,0,sub.size()-1); for (int i=0;i<sub.size();i++){ if(sub.get(i)<0){ int temp=maxsum(sub,0,i-1)+maxsum(sub,i+1,sub.size()-1); result=result>temp?result:temp; } } return result; } }
版权声明:本文博客原创文章,博客,未经同意,不得转载。