Multiple States VI¶
Description¶
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 (i.e., you must sell the stock before you buy again).
Question Link¶
https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/description/
Example I:¶
Input: [3,3,5,0,0,3,1,4]
Output: 6
Explanation: Buy on day 4 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.
Then buy on day 7 (price = 1) and sell on day 8 (price = 4), profit = 4-1 = 3.
Example II:¶
Input: [1,2,3,4,5]
Output: 4
Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
engaging multiple transactions at the same time. You must sell before buying again.
Example III:¶
Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.
Questions¶
- LeetCode - 123. Best Time to Buy and Sell Stock III
Transform Function¶
before[i] = Math.max(before[i - 1], prices[i] - min); after[i] = Math.max(after[i + 1], max - prices[i]); res = Math.max(before[i] + after[i], res);
Template I¶
class Solution { public int maxProfit(int[] prices) { if (prices == null || prices.length <= 1) return 0; int n = prices.length; int[] before = new int[n]; int min = prices[0]; for(int i = 1; i < n; i++) { min = Math.min(min, prices[i]); before[i] = Math.max(before[i - 1], prices[i] - min); } int[] after = new int[n]; int max = prices[n - 1]; for(int i = n - 2; i >= 0; i--) { max = Math.max(prices[i], max); after[i] = Math.max(after[i + 1], max - prices[i]); } int res = 0; for(int i = 0; i < n; i++) res = Math.max(before[i] + after[i], res); return res; } }
Optimized¶
hold_one[i] = Math.max(-prices[i], hold_one[i - 1]) hold_one_sell_one = Math.max(hold_one[i - 1] + prices[i], hold_one_sell_one[i - 1]) hold_two_sell_one = Math.max(hold_one_sell_one[i - 1] - prices[i], hold_two_sell_one[i - 1]) hold_two_sell_two = Math.max(hold_two_sell_one[i - 1] + prices[i], hold_two_sell_two[i - 1])
Template II¶
class Solution { public int maxProfit(int[] prices) { if(prices == null || prices.length == 0) return 0; int n = prices.length; int[] holdOne = new int[n + 1]; int[] holdOneSellOne = new int[n + 1]; int[] holdTwoSellOne = new int[n + 1]; int[] holdTwoSellTwo = new int[n + 1]; holdOne[0] = Integer.MIN_VALUE; holdTwoSellOne[0] = Integer.MIN_VALUE; for(int i = 1; i <= n; i++) { holdOne[i] = Math.max(holdOne[i - 1], -prices[i - 1]); holdOneSellOne[i] = Math.max(holdOneSellOne[i - 1], holdOne[i - 1] + prices[i - 1]); holdTwoSellOne[i] = Math.max(holdTwoSellOne[i - 1], holdOneSellOne[i - 1] - prices[i - 1]); holdTwoSellTwo[i] = Math.max(holdTwoSellTwo[i - 1], holdTwoSellOne[i - 1] + prices[i - 1]); } return holdTwoSellTwo[n]; } }
Optimized¶
int hold_one = Integer.MIN_VALUE; int hold_one_sell_one = 0; int hold_two_sell_one = Integer.MIN_VALUE; int hold_two_sell_two = 0;
Template III¶
class Solution { public int maxProfit(int[] prices) { int hold_one = Integer.MIN_VALUE, hold_one_sell_one = 0; int hold_two_sell_one = Integer.MIN_VALUE; int hold_two_sell_two = 0; for(int p : prices) { hold_one = Math.max(hold_one, -p); hold_one_sell_one = Math.max(hold_one + p, hold_one_sell_one); hold_two_sell_one = Math.max(hold_one_sell_one - p, hold_two_sell_one); hold_two_sell_two = Math.max(hold_two_sell_one + p, hold_two_sell_two); } return hold_two_sell_two; } }