Skip to content

Commit aa71b76

Browse files
committed
feat(dp): buy & sell stock
1 parent 3c1d82d commit aa71b76

File tree

6 files changed

+121
-0
lines changed

6 files changed

+121
-0
lines changed

puzzles/arrays/max_profit/README.md renamed to algorithms/dynamic_programming/buy_sell_stock/README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,46 @@ Input: prices = [7,6,4,3,1]
8585
Output: 0
8686
Explanation: In this case, no transaction is done, i.e. max profit = 0.
8787
```
88+
89+
---
90+
91+
# Best Time To Buy and Sell Stock With Transaction Fee
92+
93+
You are given an array prices where prices[i] is the price of a given stock on the ith day, and an integer fee
94+
representing a transaction fee.
95+
96+
Find the maximum profit you can achieve. You may complete as many transactions as you like, but you need to pay the
97+
transaction fee for each transaction.
98+
99+
Note:
100+
101+
You may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again).
102+
The transaction fee is only charged once for each stock purchase and sale.
103+
104+
Example 1:
105+
106+
```text
107+
Input: prices = [1,3,2,8,4,9], fee = 2
108+
Output: 8
109+
Explanation: The maximum profit can be achieved by:
110+
- Buying at prices[0] = 1
111+
- Selling at prices[3] = 8
112+
- Buying at prices[4] = 4
113+
- Selling at prices[5] = 9
114+
The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8.
115+
```
116+
117+
Example 2:
118+
119+
```text
120+
Input: prices = [1,3,7,5,10,3], fee = 3
121+
Output: 6
122+
```
123+
124+
# Related topics
125+
126+
- Arrays
127+
- Dynamic Programming
128+
- Greedy
129+
130+

puzzles/arrays/max_profit/__init__.py renamed to algorithms/dynamic_programming/buy_sell_stock/__init__.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import math
12
from typing import List
23

34

@@ -93,3 +94,29 @@ def max_profit_3(prices: List[int]) -> int:
9394
profit = max(profit, forward_profit[day] + backward_profit[day])
9495

9596
return profit
97+
98+
99+
def max_profit_with_fee(prices: List[int], fee: int) -> int:
100+
# initially, there is no cash
101+
initial_cash = -math.inf
102+
# initial profit is 0
103+
current_profit = 0
104+
105+
for price in prices:
106+
# Maximum cash in hand with shares
107+
# Either
108+
# 1. withold prev share in which case your cash in hand will not change,
109+
# 2. or assume there was no currently bought share but you want to buy it today -
110+
# In this case: your current cash in hand with shares will be your previous cash
111+
# in hand without shares minus buying price of the share today.
112+
initial_cash = max(initial_cash, current_profit - price)
113+
114+
# Maximum cash in hand without shares
115+
# Either
116+
# 1. withold money without shares in which case your cash in hand will not change,
117+
# 2. or assume you previously bought the share and you are going to sell that today -
118+
# In this case : your current cash in hand without shares will be your previous cash
119+
# in hand with shares plus the current selling price minus transaction fee
120+
current_profit = max(current_profit, initial_cash + price - fee)
121+
122+
return current_profit
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import unittest
2+
3+
from . import max_profit_with_fee
4+
5+
6+
class MaxProfitWithFeeTestCases(unittest.TestCase):
7+
def test_empty_array(self):
8+
nums = []
9+
expected = 0
10+
actual = max_profit_with_fee(nums, 4)
11+
self.assertEqual(expected, actual)
12+
13+
def test_prices_are_same(self):
14+
nums = [1, 1, 1, 1]
15+
expected = 0
16+
actual = max_profit_with_fee(nums, 4)
17+
self.assertEqual(expected, actual)
18+
19+
def test_single_element_array(self):
20+
nums = [1]
21+
expected = 0
22+
actual = max_profit_with_fee(nums, 1)
23+
self.assertEqual(expected, actual)
24+
25+
def test_4(self):
26+
"""should return 8 for prices=1,3,2,8,4,9 and fee of 2"""
27+
nums = [1, 3, 2, 8, 4, 9]
28+
fee = 2
29+
expected = 8
30+
actual = max_profit_with_fee(nums, fee)
31+
self.assertEqual(expected, actual)
32+
33+
def test_5(self):
34+
"""should return 6 for prices=1,3,7,5,10,3 and fee of 3"""
35+
nums = [1, 3, 7, 5, 10, 3]
36+
fee = 3
37+
expected = 6
38+
actual = max_profit_with_fee(nums, fee)
39+
self.assertEqual(expected, actual)
40+
41+
def test_6(self):
42+
"""should return 13 for prices=[1,4,6,2,8,3,10,14] and fee of 3"""
43+
nums = [1, 4, 6, 2, 8, 3, 10, 14]
44+
fee = 3
45+
expected = 13
46+
actual = max_profit_with_fee(nums, fee)
47+
self.assertEqual(expected, actual)
48+
49+
50+
if __name__ == "__main__":
51+
unittest.main()

0 commit comments

Comments
 (0)