Skip to content

Commit ea808c3

Browse files
committed
Implement best-time-to-buy-and-sell-stock
https://leetcode.com/problems/best-time-to-buy-and-sell-stock time: 8ms time-rank: 94.45% time-complexity: O(N) space: 13.4MB space-rank: 43.10% space-complexity: O(1) Fixes #230 Signed-off-by: Christopher Friedt <[email protected]>
1 parent 9a69417 commit ea808c3

File tree

2 files changed

+151
-0
lines changed

2 files changed

+151
-0
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2020 Christopher Friedt
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
#include <gtest/gtest.h>
26+
27+
#include "best-time-to-buy-and-sell-stock.cpp"
28+
29+
using namespace std;
30+
31+
TEST(BestTimeToBuyAndSellStock, 7_1_5_3_6_4) {
32+
auto prices = vector<int>{7, 1, 5, 3, 6, 4};
33+
EXPECT_EQ(5, Solution().maxProfit(prices));
34+
}
35+
36+
TEST(BestTimeToBuyAndSellStock, 7_6_4_3_1) {
37+
auto prices = vector<int>{7, 6, 4, 3, 1};
38+
EXPECT_EQ(0, Solution().maxProfit(prices));
39+
}

best-time-to-buy-and-sell-stock.cpp

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2020 Christopher Friedt
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
#include <limits.h>
26+
27+
#include <vector>
28+
29+
using namespace std;
30+
31+
class Solution {
32+
public:
33+
int maxProfit(vector<int> &prices) {
34+
// the naive solution is O(N^2)
35+
// max_profit = 0;
36+
// for (int i = 0; i < prices.size(); ++i) {
37+
// int buy_price = prices[i];
38+
// for(int j = i + 1; j < prices.size(); ++j) {
39+
// int sell_price = prices[j];
40+
// int profit = sell_price - buy_price;
41+
// if (profit > max_profit) {
42+
// max_profit = profit;
43+
// }
44+
// }
45+
// }
46+
// return max_profit;
47+
48+
// We need to do better than O(N^2).
49+
// - O(logN) impossible because we must consider all prices (so >= O(N))
50+
// - O(N) can we do this using DP?
51+
//
52+
// 1. Can the ideal solution be expressed using a recursion?
53+
// for each day, i
54+
// MP(i) = 0: if i == -1
55+
// = MP(i-1): if profit(i) <= MP(i-1)
56+
// = profit(i), otherwise
57+
// profit(i) = sell_price(i) - buy_price(i)
58+
// = P[i] - min(P[0]..P[i])
59+
// 2. Is there an optimal substructure?
60+
// - yes! the MP for each day is a maximization of solutions to
61+
// subproblems
62+
// 3. Are there overlapping subproblems?
63+
// - technically no. the "min" problem only requires 1 value to be
64+
// remembered
65+
// - based on the above, the "MP" problem also only requires a history of
66+
// 1
67+
//
68+
// - just because the problem can be expressed recursively does not imply
69+
// it requires a DP solution.
70+
//
71+
// - because previous calculations are used at most once, there are not
72+
// overlapping
73+
// subproblems, and therefore it is not a DP solution.
74+
//
75+
// Still, can we do it in linear time?
76+
// - Yes!
77+
//
78+
// 4. Initial conditions?
79+
// * MP(i) is poorly defined for i = 0, so lets define MP(-1) to be 0
80+
// * P[-1] can be considered to be infinity
81+
// 5. Change of indices.
82+
// - let j = i + 1
83+
// - we will iterate with j in [0, N], where N is included in the range
84+
//
85+
// Example
86+
// j | 0 | 1 | 2 | 3 | 4 | 5 | 6
87+
// -------------------------------------
88+
// P | inf | 7 | 1 | 5 | 3 | 6 | 4
89+
// minp | - | 7 | 1 | 1 | 1 | 1 | 1
90+
// profit | - | 0 | 0 | 4 | 2 | 5 | 3
91+
// MP | 0 | 0 | 0 | 4 | 4 | 5 | 5
92+
//
93+
// Now we have done solved the problem in O(N) time!!
94+
//
95+
// However, our solution above uses O(N) space as well.
96+
//
97+
// Can this be done in O(1) space?? Of course!
98+
99+
int max_profit = 0;
100+
int minp = INT_MAX;
101+
vector<int> &P = prices;
102+
103+
for (int i = 0, N = P.size(); i < N; ++i) {
104+
minp = min(minp, P[i]);
105+
// hypothetical profit if we were to sell today
106+
int profit = P[i] - minp;
107+
max_profit = max(max_profit, profit);
108+
}
109+
110+
return max_profit;
111+
}
112+
};

0 commit comments

Comments
 (0)