π One-stop destination for all your technical interview Preparation π
You are given an integer array prices where prices[i] is the price of a given stock on the ith day, and an integer k.
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).
Note that you could also set up the solution so that transactions are completed upon buying a stock instead.
Pseudo code
dp(i, transactionsRemaining, holding) = max(doNothing, sellStock) if holding == 1
otherwise max(doNothing, buyStock)
Where,
doNothing = dp(i + 1, transactionsRemaining, holding),
sellStock = prices[i] + dp(i + 1, transactionsRemaining - 1, 0),
buyStock = -prices[i] + dp(i + 1, transactionsRemaining, 1).
// i = day i, k = transactions, holdings = 0/1
class Solution {
private:
int maxProfitRec(vector<int>& prices, int k, int i, int holding)
{
// if not transactions remaining OR no days remaining(i>=prices.size())
if (k == 0 || i >= prices.size())
return 0;
int doNothing = maxProfitRec(prices, k, i + 1, holding);
// if holding, sell/not sell
if (holding) {
int sellStock = maxProfitRec(prices, k - 1, i + 1, 0) + prices[i];
return max(doNothing, sellStock);
} else { // not holding, buy/not buy
int buyStock = maxProfitRec(prices, k, i + 1, 1) - prices[i];
return max(doNothing, buyStock);
}
}
public:
int maxProfit(int k, vector<int>& prices)
{
return maxProfitRec(prices, k, 0, 0);
}
};
// i = day i, k = transactions, holdings = 0/1
class Solution {
private:
int dp[1001][101][2];
int maxProfitRec(vector<int>& prices, int k, int i, int holding)
{
// if not transactions remaining OR no days remaining(i>=prices.size())
if (k == 0 || i >= prices.size())
return 0;
// if we have already calculated this state, return it
if (dp[i][k][holding] != 0)
return dp[i][k][holding];
int doNothing = maxProfitRec(prices, k, i + 1, holding);
// if holding, sell/not sell
if (holding) {
int sellStock = maxProfitRec(prices, k - 1, i + 1, 0) + prices[i];
return dp[i][k][holding] = max(doNothing, sellStock);
} else { // not holding, buy/not buy
int buyStock = maxProfitRec(prices, k, i + 1, 1) - prices[i];
return dp[i][k][holding] = max(doNothing, buyStock);
}
}
public:
int maxProfit(int k, vector<int>& prices)
{
return maxProfitRec(prices, k, 0, 0);
}
};
// i = day i, k = transactions, holdings = 0/1
class Solution {
public:
int maxProfit(int k, vector<int>& prices)
{
// dp[n+1][k+1][2] = max profit for n days, k transactions, holding 0/1
int n = prices.size();
int dp[n + 1][k + 1][2];
memset(dp, 0, sizeof(dp));
for (int i = n - 1; i >= 0; i--) { // days from last to first
for (int transRem = 1; transRem <= k; transRem++) { // transactions remaining
for (int holding = 0; holding < 2; holding++) { // holding 0/1
int doNothing = dp[i + 1][transRem][holding];
int doSomething = 0;
if (holding == 1) {
// Sell stock
doSomething = prices[i] + dp[i + 1][transRem - 1][0];
} else {
// Buy stock
doSomething = -prices[i] + dp[i + 1][transRem][1];
}
// Recurrence relation
dp[i][transRem][holding] = max(doNothing, doSomething);
}
}
}
return dp[0][k][0]; // returns max profit for k transactions
}
};