Best Time to Buy and Sell Stock III(JAVA)-動態規劃
阿新 • • 發佈:2019-02-04
題目:
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).
翻譯:
有一個數組表示股票每天的價格,你總共可以交易兩次,但每次只能買一支或者賣一支股票,且手上最多隻能擁有一支股票,即在買第二支股票前,必須先將第一支股票賣出。設計一個演算法,求最大收益
例如,陣列 prices = {3,2,6,5,0,3}表示股票每天的價格,則最大收益為:(6-2) +(3-0)=7;
思路:
1、假設只能交易一次,求出每天之前的最大收益,用陣列Profit表示,例如針對以上價格,可計算出Profit={0,0,4,4,4,4}
2、用1中的方法,從後往前計算最大收益 reverseProfit={4,4,3,3,3,0}
3、對陣列進行prices迴圈,計算Profit[i]+reverseProfit[i]的最大值,即為最大收益
程式碼(java)
public class Solution {
public int maxProfit(int[] prices) {
int nLen = prices.length;
if(nLen<2){
return 0;
}
int[] Profit = new int[nLen];
int minPrice = prices[0];
int maxProfit = 0;
for(int i = 1; i<nLen; i++){ //計算買一次賣一次的最大收益
if(prices[i] < minPrice){
Profit[i] = Profit[i-1];
minPrice = prices[i];
}else{
int temp = prices[i] - minPrice;
Profit[i] = Profit[i-1] > temp ? Profit[i-1] : temp;
}
}
if(nLen == 2){ //如果只有三天資料,則只能交易一次,就不進行下面的計算了
return Profit[1];
}
int maxPrice = prices[nLen-1];
int[] reverseProfit = new int[nLen];
for(int i = nLen-1; i > 1; i--){//逆向求出交易一次的最大收益
if(prices[i-1] > maxPrice){
reverseProfit[i-1] = reverseProfit[i];
maxPrice = prices[i-1];
}else{
int temp = maxPrice - prices[i-1];
reverseProfit[i-1] = reverseProfit[i] > temp ? reverseProfit[i] : temp;
}
}
for(int i = 0; i<nLen; i++){
int temp = Profit[i] + reverseProfit[i];
maxProfit = maxProfit > temp ? maxProfit : temp;
}
return maxProfit;
}
}
搜尋到的改進版(程式碼更簡單,空間複雜度降低):
public class Solution {
public int maxProfit(int[] prices) {
int hold1 = Integer.MIN_VALUE, hold2 = Integer.MIN_VALUE;
int release1 = 0, release2 = 0;
for(int i:prices){
release2 = Math.max(release2, hold2+i);
hold2 = Math.max(hold2, release1-i);
release1 = Math.max(release1, hold1+i);
hold1 = Math.max(hold1, -i);
}
return release2;
}
}