题意:
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;
}