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 from stock transactions given a constraint on the number of transactions. This problem is significant in financial applications where maximizing returns on investments is crucial. A common pitfall is to assume that buying and selling on every profitable day is optimal, which is not always the case due to the transaction limit.
To solve this problem, we need to consider both a naive and an optimized approach:
The naive approach involves trying all possible pairs of buy and sell days, which is computationally expensive and not feasible for large inputs. This approach has a time complexity of O(n^2), where n is the number of days.
We can use dynamic programming to optimize the solution. The idea is to maintain a table where each entry represents the maximum profit achievable with a given number of transactions up to a certain day. This approach has a time complexity of O(n*k), where n is the number of days and k is the number of transactions.
Here is a step-by-step breakdown of the optimized algorithm:
/**
* @param {number[]} prices
* @param {number} k
* @return {number}
*/
function maxProfit(k, prices) {
const n = prices.length;
if (n === 0) return 0;
// If k is greater than n/2, it's equivalent to unlimited transactions
if (k >= n / 2) {
let maxProfit = 0;
for (let i = 1; i < n; i++) {
if (prices[i] > prices[i - 1]) {
maxProfit += prices[i] - prices[i - 1];
}
}
return maxProfit;
}
const dp = Array.from({ length: k + 1 }, () => Array(n).fill(0));
for (let t = 1; t <= k; t++) {
let maxDiff = -prices[0];
for (let d = 1; d < n; d++) {
dp[t][d] = Math.max(dp[t][d - 1], prices[d] + maxDiff);
maxDiff = Math.max(maxDiff, dp[t - 1][d] - prices[d]);
}
}
return dp[k][n - 1];
}
The time complexity of the optimized approach 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 2D array used for dynamic programming.
Potential edge cases include:
To test the solution comprehensively, consider the following test cases:
When approaching such problems, it's essential to:
Understanding and solving the "Best Time to Buy and Sell Stock II" problem helps in developing skills in dynamic programming and optimization. Practice is key to mastering such problems.
For further reading and practice, consider the following resources: