Say you have an array for which the i-th element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete at most k transactions.
Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
Example 1:
Input: [2,4,1], k = 2 Output: 2 Explanation: Buy on day 1 (price = 2) and sell on day 2 (price = 4), profit = 4-2 = 2.
Example 2:
Input: [3,2,6,5,0,3], k = 2 Output: 7 Explanation: Buy on day 2 (price = 2) and sell on day 3 (price = 6), profit = 6-2 = 4. Then buy on day 5 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.
The core challenge of this problem is to maximize the profit by buying and selling stocks given the constraint of at most k transactions. This problem is significant in financial markets where traders aim to maximize their returns. A common pitfall is to misunderstand the constraint of not engaging in multiple transactions simultaneously.
To solve this problem, we need to consider both a naive and an optimized approach:
The naive solution involves trying all possible pairs of buy and sell days, which is not optimal due to its high time complexity of O(n^2). This approach is impractical for large inputs.
We can use dynamic programming to optimize the solution. The idea is to maintain two arrays: one for the maximum profit up to day i with at most j transactions, and another for the maximum profit up to day i with exactly j transactions.
Here is a step-by-step breakdown of the optimized algorithm:
dp
where dp[i][j]
represents the maximum profit up to day i
with at most j
transactions.k
.dp
array accordingly.#include <vector>
#include <algorithm>
using namespace std;
// Function to calculate the maximum profit
int maxProfit(int k, vector<int>& prices) {
int n = prices.size();
if (n == 0) return 0;
// If k is greater than n/2, it's equivalent to unlimited transactions
if (k >= n / 2) {
int maxProfit = 0;
for (int i = 1; i < n; ++i) {
if (prices[i] > prices[i - 1]) {
maxProfit += prices[i] - prices[i - 1];
}
}
return maxProfit;
}
// DP array to store the maximum profit
vector<vector<int>> dp(k + 1, vector<int>(n, 0));
for (int i = 1; i <= k; ++i) {
int maxDiff = -prices[0];
for (int j = 1; j < n; ++j) {
dp[i][j] = max(dp[i][j - 1], prices[j] + maxDiff);
maxDiff = max(maxDiff, dp[i - 1][j] - prices[j]);
}
}
return dp[k][n - 1];
}
The time complexity of the optimized solution is O(k * n), where k
is the number of transactions and n
is the number of days. The space complexity is also O(k * n) due to the 2D DP array.
Consider the following edge cases:
To test the solution comprehensively, consider the following test cases:
k
values.When approaching such problems, consider breaking down the problem into smaller subproblems and using dynamic programming to optimize the solution. Practice similar problems to improve your problem-solving skills.
In this blog post, we discussed the problem of finding the best time to buy and sell stock with at most k
transactions. We explored both naive and optimized solutions, provided a detailed algorithm, and analyzed the complexity. Understanding and solving such problems is crucial for improving algorithmic thinking and problem-solving skills.
For further reading and practice, consider the following resources: