forked from haoel/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bestTimeToBuyAndSellStock.IV.cpp
135 lines (118 loc) · 5.17 KB
/
bestTimeToBuyAndSellStock.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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Source : https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/
// Author : Hao Chen
// Date : 2015-03-31
/*****************************************************************************************************
*
* Say you have an array for which the ith 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.
******************************************************************************************************/
class Solution {
public:
/*
* profits[trans, day]
* - `trans` represents the number of transactions we've done so far. ( 0 <= trans <= k )
* - `day` represents the number of days so far. ( 0 <= day <= prices.size() )
*
* So, we have the initialization as below:
*
* profits[0, day] = 0; // 0 <= day <= prices.size()
* profits[trans, 0] = 0; // 0 <= trans <= k
*
* And the iteration logic as below:
*
* profits[trans, day] = max (
* profits[trans, day-1], // same times transactions, but one days before.
* profits[trans-1, i-1] + (prices[day] - prices[i]) // for all of (0 <= i < day )
* // this means find max profit from
* // previous any of days
* )
*
*/
int maxProfit(int k, vector<int> &prices) {
int ndays = prices.size();
// error case
if (ndays<=1) return 0;
// Edge case
// ---------
// if the number of transactions is too many, it means we can make
// as many transactions as we can, that brings us the problem back to
// Best-Time-To-Buy-And-Sell-Stock-II which can be simply solve in O(n)
// by using a greedy approach.
if(k > ndays/2){
int sum = 0;
for (int i=1; i<ndays; i++) {
sum += max(prices[i] - prices[i-1], 0);
}
return sum;
}
return maxProfit_DP03(k, prices);//8ms
return maxProfit_DP02(k, prices);//8ms
return maxProfit_DP01(k, prices);//492ms
}
//DP solution - O(kn^2) complexity
int maxProfit_DP01 (int k, vector<int> &prices) {
int ndays = prices.size();
vector< vector<int> > profits(k+1, vector<int>( ndays+1, 0));
for(int trans=1; trans<=k; trans++) {
for (int day=1; day<=ndays; day++) {
int m=0;
for (int i=1; i<=day; i++) {
m = max(m, profits[trans-1][i-1]+ prices[day-1] - prices[i-1]);
}
profits[trans][day] = max( profits[trans][day-1], m);
}
}
return profits[k][ndays];
}
//DP solution - O(kn) complexity
//Actually, we could save the loop in above- for(int i=1; i<=day; i++)
//Becasue there are so many dupliations
int maxProfit_DP02 (int k, vector<int> &prices) {
int ndays = prices.size();
vector< vector<int> > profits(k+1, vector<int>( ndays+1, 0));
vector<int> m(ndays+1, 0); // tracking the max profits of previous days
for(int trans=1; trans<=k; trans++) {
m[0] = profits[trans-1][0] - prices[0];
for (int day=1; day<=ndays; day++) {
profits[trans][day] = max( profits[trans][day-1], m[day-1]+prices[day-1]);
if (day < ndays) {
m[day] = max(m[day-1], profits[trans-1][day] - prices[day]);
}
}
}
return profits[k][ndays];
}
// save the memory, remove the m[ ] array
int maxProfit_DP03 (int k, vector<int> &prices) {
int ndays = prices.size();
vector< vector<int> > profits(k+1, vector<int>( ndays+1, 0));
for(int trans=1; trans<=k; trans++) {
int m = profits[trans-1][0] - prices[0];
for (int day=1; day <= ndays; day++) {
profits[trans][day] = max(profits[trans][day-1], m + prices[day-1]);
if ( day < ndays ) {
m = max(m, profits[trans-1][day] - prices[day]);
}
}
}
return profits[k][ndays];
}
};