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 making at most k transactions. A transaction consists of buying and then selling one share of the stock. The constraint is that you cannot engage in multiple transactions simultaneously, meaning you must sell the stock before you can buy again.
This problem is significant in financial markets where traders aim to maximize their returns by strategically buying and selling stocks. A common pitfall is to assume that you can buy and sell on the same day or engage in multiple transactions simultaneously, which is not allowed.
To solve this problem, we can use dynamic programming. The idea is to maintain a table where the entry dp[i][j]
represents the maximum profit achievable using at most i
transactions up to day j
.
A naive solution would involve trying all possible pairs of buy and sell days for each transaction, which would be computationally expensive and not feasible for large inputs.
We can optimize the solution using dynamic programming. The key observation is that the maximum profit up to day j
with i
transactions can be derived from the maximum profit up to day j-1
with i
transactions and the maximum profit up to day m
with i-1
transactions plus the profit from buying on day m
and selling on day j
.
1. Initialize a 2D array dp
where dp[i][j]
represents the maximum profit using at most i
transactions up to day j
.
2. Iterate over the number of transactions from 1 to k
.
3. For each transaction, iterate over the days from 1 to n-1
.
4. For each day, calculate the maximum profit by considering the maximum profit up to the previous day and the maximum profit from any previous day plus the profit from buying on that day and selling on the current day.
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;
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 table
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 this solution is O(n*k)
, where n
is the number of days and k
is the number of transactions. The space complexity is also O(n*k)
due to the DP table.
1. If the number of days n
is 0, the maximum profit is 0.
2. If k
is greater than or equal to n/2
, it is equivalent to unlimited transactions.
3. If the prices array is strictly decreasing, the maximum profit is 0.
To test the solution comprehensively, consider the following test cases:
k
is greater than or equal to n/2
.1. Break down the problem into smaller subproblems and solve them using dynamic programming.
2. Consider edge cases and constraints to ensure the solution is robust.
3. Practice similar problems to improve problem-solving skills and understand different approaches.
In this blog post, we discussed the problem of finding the maximum profit from at most k
transactions. We explored a dynamic programming approach to solve the problem efficiently and provided a detailed explanation of the algorithm and its implementation in C++. Understanding and solving such problems is crucial for developing strong problem-solving skills and improving algorithmic thinking.