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:
1 2 3
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:
1 2 3 4
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.
classSolution{ public: intmaxProfit(int k, vector<int>& prices){ constint m = prices.size(); vector<int> profits; stack<pair<int,int>> vps; // vally-peak pairs int v = 0, p = -1; // padding p , so not using p-1 while (true) { // find next vally and peak for (v = p+1; v+1 < m && (prices[v] >= prices[v+1]); v++); for (p = v; p+1 < m && (prices[p] >= prices[p-1]); p++); if (v == p) break; // to the end of prices
// v < p
// (v1,p1) (v2,p2) // if (prices[v1] >= prices[v2]) no need to combine two transactions // after å top is (v1,p2), push p2-v1 into profit --> step ∑ while (!vps.empty() && (prices[v] <= prics[vps.top().first])) { profits.push_back(prices[vps.top().second] - prices[vps.top().first]); vps.pop(); }
// (v1, p1) (v2,p2) // if (prices[v1] < prices[v2] && prices[p1] < prices[p2]) we need to combine two transactions // update (v1,p1) --> (v1, p2) // p2-v2 + p1-v1 == p2-v1 + p1-v2 // after step ∑ top is (v1, p2) while (!vps.empty() && (prices[p] >= prices[vps.top().second])) { // save profit (v2, p1) profits.push_back(prices[vps.top().second] - prices[v]); // v1 --> v v = vps.top()first; vps.pop(); // v is v1 // p is p2 // step å } // if step å (v1, p2) is top of vps vps.push(make_pair(v, p)); } }
// calculate all the profits while (!vps.empty()) { profits.push_back(prices[vps.top().second] - prices[vps.top().first]); vps.pop(); }
// calculate k highest profitœ int ans = 0; constint n = profits.size(); if (n < = k) { accumulate(profits.begin(), profits.end(), 0); } else { nth_element(profits.begin(), profits.end() - k, profits.end()); accumulate(profits.end() - k,profit.end(), 0); } return ans; };