forked from ligua/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbest-time-to-buy-and-sell-stock-iv.cpp
44 lines (43 loc) · 2.21 KB
/
best-time-to-buy-and-sell-stock-iv.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// Time: O(n)
// Space: O(n)
class Solution {
public:
int maxProfit(int k, vector<int> &prices) {
vector<int> profits;
vector<pair<int, int>> v_p_stk; // mono stack, where v is increasing and p is strictly decreasing
for (int v = -1, p = -1; p + 1 < size(prices);) { // at most O(n) peaks, so v_p_stk and profits are both at most O(n) space
for (v = p + 1; v + 1 < size(prices); ++v) {
if (prices[v] < prices[v + 1]) {
break;
}
}
for (p = v; p + 1 < size(prices); ++p) {
if (prices[p] > prices[p + 1]) {
break;
}
}
while (!empty(v_p_stk) && (prices[v_p_stk.back().first] > prices[v])) { // not overlapped
const auto [last_v, last_p] = move(v_p_stk.back()); v_p_stk.pop_back();
profits.emplace_back(prices[last_p] - prices[last_v]); // count [prices[last_v], prices[last_p]] interval
}
while (!empty(v_p_stk) && (prices[v_p_stk.back().second] <= prices[p])) { // overlapped
// prices[last_v] <= prices[v] <= prices[last_p] <= prices[p],
// treat overlapped as [prices[v], prices[last_p]], [prices[last_v], prices[p]] intervals due to invariant max profit
const auto [last_v, last_p] = move(v_p_stk.back()); v_p_stk.pop_back();
profits.emplace_back(prices[last_p] - prices[v]); // count [prices[v], prices[last_p]] interval
v = last_v;
}
v_p_stk.emplace_back(v, p); // keep [prices[last_v], prices[p]] interval to check overlapped
}
while (!empty(v_p_stk)) {
const auto [last_v, last_p] = move(v_p_stk.back()); v_p_stk.pop_back();
profits.emplace_back(prices[last_p] - prices[last_v]); // count [prices[last_v], prices[last_p]] interval
}
if (k > size(profits)) {
k = size(profits);
} else {
nth_element(begin(profits), begin(profits) + k - 1, end(profits), greater<int>());
}
return accumulate(cbegin(profits), cbegin(profits) + k, 0); // top k profits of nonoverlapped intervals
}
};