1. 程式人生 > >Best Time to Buy and Sell Stock III(JAVA)-動態規劃

Best Time to Buy and Sell Stock III(JAVA)-動態規劃

題目:
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; 
    }
}