Skip to content

Commit ff56543

Browse files
authored
Create README.md
1 parent 5f1e329 commit ff56543

File tree

1 file changed

+374
-0
lines changed
  • 24 - Dynamic Programming Problems/31 - Best Time to Buy and Sell Stock

1 file changed

+374
-0
lines changed
Lines changed: 374 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,374 @@
1+
<h1 align="center">Best - Time To - Buy & Sell - Stock</h1>
2+
3+
## Problem Statement
4+
5+
**Problem URL :** [Best Time To Buy & Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/)
6+
7+
![image](https://github.com/user-attachments/assets/d23bc577-41f3-4a39-b8ab-f2432ad156df)
8+
9+
### Problem Explanation
10+
11+
The problem asks us to find the **maximum profit** we can achieve from buying and selling a stock at different times. You are given a list of stock prices where each price corresponds to the price of the stock on a particular day. The goal is to determine **the best time to buy and the best time to sell** in order to maximize the profit.
12+
13+
You are allowed to make **only one transaction** (i.e., you can buy and sell the stock once). You must buy the stock first, then sell it at a later date.
14+
15+
### Key Points:
16+
17+
1. **You must buy before you sell.**
18+
2. **You are allowed to make only one buy and one sell.**
19+
3. You are to find the maximum profit that can be made from buying and selling at different times.
20+
21+
If no profit can be made (i.e., the stock price only decreases over time), the result should be **0**.
22+
23+
### Input:
24+
25+
- A list of integers `prices`, where each element represents the stock price on a particular day.
26+
27+
### Output:
28+
29+
- An integer that represents the **maximum profit** that can be achieved. If no profit is possible, return **0**.
30+
31+
32+
### Example 1:
33+
34+
**Input:**
35+
36+
```cpp
37+
prices = [7, 1, 5, 3, 6, 4]
38+
```
39+
40+
**Explanation:**
41+
42+
- On Day 1, the price is 7.
43+
- On Day 2, the price is 1 (this is the lowest price, so it's a good time to buy).
44+
- On Day 3, the price is 5 (this is a higher price, so you could sell here).
45+
- On Day 4, the price is 3.
46+
- On Day 5, the price is 6 (this is another potential time to sell).
47+
- On Day 6, the price is 4.
48+
49+
The **best strategy** here is:
50+
- Buy at Day 2 (price = 1).
51+
- Sell at Day 5 (price = 6).
52+
53+
The profit is:
54+
- **Profit = 6 - 1 = 5**.
55+
56+
Thus, the maximum profit is **5**.
57+
58+
**Output:**
59+
60+
```cpp
61+
5
62+
```
63+
64+
65+
### Example 2:
66+
67+
**Input:**
68+
69+
```cpp
70+
prices = [7, 6, 4, 3, 1]
71+
```
72+
73+
**Explanation:**
74+
75+
- On Day 1, the price is 7.
76+
- On Day 2, the price is 6.
77+
- On Day 3, the price is 4.
78+
- On Day 4, the price is 3.
79+
- On Day 5, the price is 1.
80+
81+
In this case, the price keeps decreasing every day. **No profit can be made** because you would have to sell the stock at a lower price than you bought it. Therefore, the best strategy is not to buy or sell at all.
82+
83+
The maximum profit is **0**.
84+
85+
**Output:**
86+
87+
```cpp
88+
0
89+
```
90+
91+
### Example 3:
92+
93+
**Input:**
94+
95+
```cpp
96+
prices = [1, 2]
97+
```
98+
99+
**Explanation:**
100+
101+
- On Day 1, the price is 1.
102+
- On Day 2, the price is 2.
103+
104+
In this case, you can:
105+
- Buy on Day 1 (price = 1).
106+
- Sell on Day 2 (price = 2).
107+
108+
The profit is:
109+
- **Profit = 2 - 1 = 1**.
110+
111+
Thus, the maximum profit is **1**.
112+
113+
**Output:**
114+
115+
```cpp
116+
1
117+
```
118+
119+
### Approach to Solve the Problem:
120+
121+
1. **Brute Force Approach:**
122+
- Try every possible pair of buy and sell days. For each pair, calculate the profit (sell price - buy price) and keep track of the maximum profit.
123+
- This approach has a time complexity of (O(n^2)), where (n) is the number of days. This can be inefficient for larger inputs.
124+
125+
2. **Optimized Approach (Linear Scan):**
126+
- Instead of trying every pair, we can **keep track of the minimum price** seen so far as we iterate through the list. For each price, calculate the potential profit (current price - minimum price) and update the maximum profit.
127+
- This approach only requires one pass through the list, giving us a time complexity of (O(n)).
128+
129+
**Steps in the optimized approach:**
130+
1. Initialize `min_price` to a large value (or the first element in the list) and `max_profit` to 0.
131+
2. Loop through each price in the list:
132+
- Update `min_price` if the current price is lower than `min_price`.
133+
- Calculate the potential profit for the current price (current price - `min_price`).
134+
- Update `max_profit` if the current profit is higher than `max_profit`.
135+
3. Return the `max_profit` after the loop ends.
136+
137+
## Problem Solution
138+
```cpp
139+
class Solution {
140+
public:
141+
int maxProfit(vector<int>& prices) {
142+
// Initialize the minimum price to the first day's price
143+
int mini = prices[0];
144+
145+
// Initialize the maximum profit to 0
146+
int profit = 0;
147+
148+
// Iterate through the price list starting from the second day
149+
for(int i = 1; i < prices.size(); i++) {
150+
// Calculate the potential profit if the stock is sold on the current day
151+
int diff = prices[i] - mini;
152+
153+
// Update the maximum profit if the current profit is higher
154+
profit = max(profit, diff);
155+
156+
// Update the minimum price seen so far
157+
mini = min(mini, prices[i]);
158+
}
159+
160+
// Return the maximum profit found
161+
return profit;
162+
}
163+
};
164+
```
165+
166+
## Problem Solution Explanation
167+
168+
```cpp
169+
class Solution {
170+
public:
171+
int maxProfit(vector<int>& prices) {
172+
```
173+
- **Line 1-2**: A class `Solution` is defined, and within it, there is a method `maxProfit` that accepts a reference to a vector of integers (`prices`). This vector represents the stock prices on each day.
174+
175+
176+
177+
```cpp
178+
// Initialize the minimum price to the first day's price
179+
int mini = prices[0];
180+
```
181+
- **Line 3**: We initialize `mini` to the first element of the `prices` array, which represents the stock price on the first day. This will act as the starting "minimum price" that we are tracking.
182+
183+
**Example**:
184+
If `prices = [7, 1, 5, 3, 6, 4]`, then initially, `mini = 7`.
185+
186+
187+
188+
```cpp
189+
// Initialize the maximum profit to 0
190+
int profit = 0;
191+
```
192+
- **Line 4**: We initialize `profit` to `0`. This variable will hold the maximum profit that can be achieved. Initially, the profit is 0 because no transactions have been made yet.
193+
194+
**Example**:
195+
If `prices = [7, 1, 5, 3, 6, 4]`, initially, `profit = 0`.
196+
197+
198+
199+
```cpp
200+
// Iterate through the price list starting from the second day
201+
for(int i = 1; i < prices.size(); i++) {
202+
```
203+
- **Line 5**: We start a loop from `i = 1` because we've already set the initial `mini` to the first element of the `prices` list, so we don’t need to consider it again. We will iterate through the rest of the prices list from the second day onward.
204+
205+
**Example**:
206+
If `prices = [7, 1, 5, 3, 6, 4]`, the loop will start at `i = 1` (second day, price = 1).
207+
208+
209+
210+
```cpp
211+
// Calculate the potential profit if the stock is sold on the current day
212+
int diff = prices[i] - mini;
213+
```
214+
- **Line 6**: For each price at `i`, we calculate the potential profit if we had bought the stock at the `mini` price (the lowest price seen so far) and sold it on day `i`. The difference between the current price (`prices[i]`) and the `mini` price is stored in `diff`.
215+
216+
**Example**:
217+
For `prices = [7, 1, 5, 3, 6, 4]`:
218+
- At `i = 1` (price = 1), `diff = 1 - 7 = -6` (this is a loss, so no action is taken).
219+
- At `i = 2` (price = 5), `diff = 5 - 7 = -2` (still a loss).
220+
- At `i = 3` (price = 3), `diff = 3 - 7 = -4` (still a loss).
221+
- At `i = 4` (price = 6), `diff = 6 - 7 = -1` (still a loss).
222+
- At `i = 5` (price = 4), `diff = 4 - 7 = -3` (still a loss).
223+
224+
225+
226+
```cpp
227+
// Update the maximum profit if the current profit is higher
228+
profit = max(profit, diff);
229+
```
230+
- **Line 7**: Here, we update the `profit` variable to the maximum of the current `profit` and the newly calculated `diff`. This ensures that if the `diff` (current profit) is greater than the previously stored `profit`, we update it.
231+
232+
**Example**:
233+
For `prices = [7, 1, 5, 3, 6, 4]`:
234+
- Initially, `profit = 0`.
235+
- At `i = 1` (price = 1), `diff = -6`. Since `-6 < 0`, `profit` remains 0.
236+
- At `i = 2` (price = 5), `diff = -2`. Since `-2 < 0`, `profit` remains 0.
237+
- At `i = 3` (price = 3), `diff = -4`. Since `-4 < 0`, `profit` remains 0.
238+
- At `i = 4` (price = 6), `diff = -1`. Since `-1 < 0`, `profit` remains 0.
239+
- At `i = 5` (price = 4), `diff = -3`. Since `-3 < 0`, `profit` remains 0.
240+
241+
At this point, `profit` is still 0 because we haven't found a profitable situation yet.
242+
243+
244+
245+
```cpp
246+
// Update the minimum price seen so far
247+
mini = min(mini, prices[i]);
248+
```
249+
- **Line 8**: After calculating the profit, we update `mini` to the minimum of the current `mini` and `prices[i]`. This ensures that we always know the lowest stock price encountered so far, which is critical for calculating future profits.
250+
251+
**Example**:
252+
For `prices = [7, 1, 5, 3, 6, 4]`:
253+
- Initially, `mini = 7`.
254+
- At `i = 1` (price = 1), `mini = min(7, 1) = 1` (update `mini` to 1).
255+
- At `i = 2` (price = 5), `mini = min(1, 5) = 1` (no update needed).
256+
- At `i = 3` (price = 3), `mini = min(1, 3) = 1` (no update needed).
257+
- At `i = 4` (price = 6), `mini = min(1, 6) = 1` (no update needed).
258+
- At `i = 5` (price = 4), `mini = min(1, 4) = 1` (no update needed).
259+
260+
At the end of the loop, `mini` remains 1, which is the lowest price seen so far.
261+
262+
263+
264+
```cpp
265+
// Return the maximum profit found
266+
return profit;
267+
}
268+
};
269+
```
270+
- **Line 9-10**: After finishing the loop, we return the `profit` variable, which holds the maximum profit that could be made by buying and selling once. If no profit is possible (i.e., the prices are in descending order), `profit` will remain 0.
271+
272+
**Example**:
273+
For `prices = [7, 1, 5, 3, 6, 4]`, the final result is `profit = 5` because the best strategy is to buy at 1 and sell at 6.
274+
275+
276+
277+
### Final Explanation with Example:
278+
279+
Let's go through the example `prices = [7, 1, 5, 3, 6, 4]` step by step:
280+
281+
- Initially:
282+
- `mini = 7`
283+
- `profit = 0`
284+
285+
- **Iteration 1 (price = 1)**:
286+
- `diff = 1 - 7 = -6` (no profit)
287+
- `profit = max(0, -6) = 0` (no update)
288+
- `mini = min(7, 1) = 1` (update mini)
289+
290+
- **Iteration 2 (price = 5)**:
291+
- `diff = 5 - 1 = 4` (profit is 4)
292+
- `profit = max(0, 4) = 4` (update profit)
293+
- `mini = min(1, 5) = 1` (no update)
294+
295+
- **Iteration 3 (price = 3)**:
296+
- `diff = 3 - 1 = 2` (profit is 2)
297+
- `profit = max(4, 2) = 4` (no update)
298+
- `mini = min(1, 3) = 1` (no update)
299+
300+
- **Iteration 4 (price = 6)**:
301+
- `diff = 6 - 1 = 5` (profit is 5)
302+
- `profit = max(4, 5) = 5` (update profit)
303+
- `mini = min(1, 6) = 1` (no update)
304+
305+
- **Iteration 5 (price = 4)**:
306+
- `diff = 4 - 1 = 3` (profit is 3)
307+
- `profit = max(5, 3) = 5` (no update)
308+
- `mini = min(1, 4) = 1` (no update)
309+
310+
- At the end of the loop, the maximum profit is `5`.
311+
312+
Thus, the output for this input is **5**.
313+
314+
315+
### Time and Space Complexity Analysis
316+
317+
#### Code Recap:
318+
```cpp
319+
class Solution {
320+
public:
321+
int maxProfit(vector<int>& prices) {
322+
int mini = prices[0]; // O(1)
323+
int profit = 0; // O(1)
324+
325+
for (int i = 1; i < prices.size(); i++) { // Loop runs prices.size() - 1 times
326+
int diff = prices[i] - mini; // O(1)
327+
profit = max(profit, diff); // O(1)
328+
mini = min(mini, prices[i]); // O(1)
329+
}
330+
331+
return profit; // O(1)
332+
}
333+
};
334+
```
335+
336+
### Time Complexity
337+
1. **Initialization**:
338+
- Setting `mini` and `profit` takes (O(1)) time.
339+
340+
2. **Loop**:
341+
- The `for` loop iterates through the `prices` array exactly once, starting from the second element ((i = 1)) to the last ((i = prices.size() - 1)).
342+
- For each iteration, the operations inside the loop (calculating `diff`, updating `profit`, and updating `mini`) all take (O(1)) time.
343+
- Thus, the total time spent in the loop is proportional to the size of the array: (O(n)), where (n) is the size of `prices`.
344+
345+
3. **Return Statement**:
346+
- Returning `profit` takes (O(1)) time.
347+
348+
### Total Time Complexity:
349+
The dominant factor is the single loop through the `prices` array, which is (O(n)).
350+
Thus, **time complexity** = **(O(n))**.
351+
352+
### Space Complexity
353+
1. **Input Array**:
354+
- The input vector `prices` is provided as an argument, so its memory is not included in the space complexity.
355+
356+
2. **Variables**:
357+
- The algorithm uses a constant amount of extra space:
358+
- `mini` (stores the minimum price seen so far): (O(1))
359+
- `profit` (stores the maximum profit): (O(1))
360+
- `diff` (temporary variable for profit calculation): (O(1))
361+
362+
363+
364+
### Total Space Complexity:
365+
Since the algorithm does not use any additional data structures and only utilizes a fixed number of variables, the **space complexity** = **(O(1))**.
366+
367+
368+
### Summary:
369+
370+
- We are tracking the **minimum price** seen so far (`mini`).
371+
- At each step, we calculate the **profit** if we sold on that day and update the **maximum profit** (`profit`) if it’s greater than the previous maximum.
372+
- At the end of the loop, we return the **maximum profit** possible, which is either positive or 0 if no profit can be made.
373+
- **Time Complexity**: (O(n)), where (n) is the size of the `prices` array.
374+
- **Space Complexity**: (O(1)), as only constant space is used.

0 commit comments

Comments
 (0)