LeetCode 188. Best Time to Buy and Sell Stock IV
You are given an integer array
prices
whereprices[i]
is the price of a given stock on theith
day, and an integerk
.Find the maximum profit you can achieve. You may complete at most
k
transactions.Note: You may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again).
Similar to its predecessors, we have to find the maximum profit given an array of stock prices. However, this time it is upgraded by giving you a maximum number of transactions. So following my previous method, I created a 3D integer array dp[i][j][k], indicating the maximum profit attainable from the i-th to j-th index given k transactions. We will calculate the transfer of state by finding the maximum of the sum of the first transaction from i-th to l-th index and the maximum value from l-th to the j-th index given k-1 transactions
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
if(prices.size() <= 1)
return 0;
int dp[prices.size() + 1][prices.size() + 1][k+1];
memset(dp, 0, sizeof(dp));
// loop through number of transactions
for(int a = 1; a <=k; a++){
// loop through starting index
for(int i = prices.size() - 1; i > 0; i--){
int minx = prices[i-1];
// loop through ending index
for(int j = i + 1; j <= prices.size(); j++){
if(a > 1){
dp[i][j][a] = dp[i][j][a-1];
// loop through middle point
for(int l = i + 1; l < j; l++){
dp[i][j][a] = max(dp[i][j][a],
dp[i][l][1] + dp[l][j][a-1]);
}
}else{
minx = min(minx, prices[j-1])
dp[i][j][a] = max(dp[i][j-1][a], prices[j-1] - minx);
}
}
}
}
return dp[1][prices.size()][k];
}
};
However, as you can see, our 3D array requires an enormous amount of storage. Given the input constraints of a maximum of 1000 elements and 100 transactions, that would require a maximum of 100million elements in our storage, which is impossible. Even if replaced with vectors, which supports a larger size, we are still going to get a TLE...
So, I changed the approach a little bit. Instead of a 3-D array, I am now using one with 1 less dimension. dp[i][j] means doing j transactions starting from i-th index up to the end of the array. The transfer of state would still be similar to the one above. As for how we are going to calculate the maximum profit in the left array, i.e. the first transaction. we are simply going to do it in our old-fashioned way, by finding its minimum and finding the maximum difference in that part.
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
if(prices.size() <= 1)
return 0;
int dp[prices.size()][k+1];
memset(dp, 0, sizeof(dp));
int m;
// loop through the number of transactions
for(int a = 1; a <= k; a++){
// loop through the starting index
for(int i = 0; i < prices.size() - 1; i++){
m = prices[i];
// loop through the middle point
for(int j = i + 1; j < prices.size(); j++){
dp[i][a] = max(dp[i][a], prices[j] - m + dp[j][a-1]);
m = min(m, prices[j]);
}
}
}
return dp[0][k];
}
};
Note that we are doing some preprocessing in the first part. Since when k = 1, it is just a simple version of the stock question. The old way would suffice.
P.S. Though my implementation is pretty slow (only faster than 5%...), I got a pass in my first trial for my second implementation :)