Skip to content

123 Best Time to Buy and Sell Stock III – Hard

Problem:

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).

Thoughts:

We will need to divide this problem into two subproblem. We find the max profit for range 0..i and i + 1..n -1, then we add up the two max profit we will get the expected result.

Solutions:

public class Solution {
    public int maxProfit(int[] prices) {
        int[] first = new int[prices.length];
        //first[i] is the max profit for the range 0 .. i, 
        int minPrice = Integer.MAX_VALUE;
        int max = 0;
        for (int i = 0; i < prices.length; i ++) {
            minPrice = Math.min(minPrice, prices[i]);
            max = Math.max(max, prices[i] - minPrice);
            first[i] =  max;
        }
        int maxPrice = Integer.MIN_VALUE;
        max = 0;
        for (int i = prices.length - 1; i > 0; i --) {
            maxPrice = Math.max(maxPrice, prices[i]);
            max = Math.max(max, maxPrice - prices[i] + first[i-1]);
        }
        if (prices.length > 0) {
            max = Math.max(max, first[first.length - 1]);
        }
        return max;
    }
}
class Solution {
    public int maxProfit(int[] prices) {
        int[][][] dp = new int[prices.length+1][3][2];
        int res = 0;
        dp[0][0][0] = dp[0][1][0] = dp[0][2][0] = 0 ;
        dp[0][0][1] = dp[0][1][1] = dp[0][2][1] = Integer.MIN_VALUE;

        for (int i = 1; i <= prices.length; i ++) {
            dp[i][0][0] = 0;
            dp[i][0][1] = Integer.MIN_VALUE;
            dp[i][1][0] = Math.max(dp[i-1][1][0], dp[i-1][1][1] + prices[i-1]);
            dp[i][1][1] = Math.max(dp[i-1][1][1], dp[i-1][0][0] - prices[i-1]);
            dp[i][2][0] = Math.max(dp[i-1][2][0], dp[i-1][2][1] + prices[i-1]);
            dp[i][2][1] = Math.max(dp[i-1][2][1], dp[i-1][1][0] - prices[i-1]);
            System.out.println(dp[i][1][0] +", " + dp[i][1][1] + ", " + dp[i][2][0] + ", " + dp[i][2][1]);
            for (int j = 0; j < 3; j ++) {
                for (int k = 0; k < 2; k ++) {
                    res = Math.max(res, dp[i][j][k]);
                }
            }
        }
        return res;
    }
}