題意:
i:交易一次,求買入賣出得到的最大利潤。
ii:交易無限次,但不能在同一時間進行多次交易。
iii:交易二次,求買入賣出得到的最大利潤。
思路:
i:只須找出價格序列中的最大最小值。低進高出,最低的一天要在最高的一天之前,貪心解決。
代碼:
public int ProfitMax(int[] prices){
if(prices == null || prices.length < 1) return prices[0];
int profit = 0;
int cur_min = prices[0];
for(int i = 0 ; i < prices.length ; i++){
profit = Math.max(profit, prices[i]-cur_min);
cur_min = Math.min(cur_min, prices[i]);
}
return profit;
}
ii:只要交易的差值爲正,就加入交易總金額中。
public int ProfitMax(int[] prices){
if(prices == null || prices.length<1 ) return prices[0];
int sum = 0;
for (int i = 1; i < prices.length; i++) {
int diff = prices[i] - prices[i-1];
if(diff > 0) sum += diff;
}
return sum;
}
iii:動態規劃解決。維護兩個數組preProfits和postProfits,分別從前和從後面對價格進行利潤值的計算。計算方式和i中的一樣,最後把兩者相加,得到最大值。
代碼:
public int ProfitMax(int[] prices){
if(prices == null || prices.length < 1) return prices[0];
int[] preProfits = new int[prices.length+1];
int[] postProfits = new int[prices.length+1];
int cur_min = prices[0];
for (int i = 1; i < prices.length; i++) {
cur_min = Math.min(cur_min, prices[i]);
preProfits[i] = Math.max(preProfits[i-1], prices[i]-cur_min);
}
for(int i = prices.length -2 , curMax = prices[prices.length-1]; i>= 0 ;i-- ){
curMax= Math.max(curMax, prices[i]);
postProfits[i] = Math.max(postProfits[i], curMax-prices[i]);
}
int max_profit = 0;
for (int i = 0; i < prices.length; i++) {
max_profit = Math.max(max_profit, preProfits[i]+postProfits[i]);
}
return max_profit;
}