Skip to content

Commit 22b7eee

Browse files
committed
Stock Buy Sell Transaction Problem. (Improvements)
1 parent c8eec64 commit 22b7eee

1 file changed

Lines changed: 69 additions & 42 deletions

File tree

Lines changed: 69 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,91 @@
1-
# buy sell stocks to maximize profit with at most k transactions
1+
""""
2+
Problem Statement
3+
=================
4+
5+
Given certain stock values over a period of days (d days) and a number K, the number of transactions allowed, find the
6+
maximum profit that be obtained with at most K transactions.
7+
8+
Video
9+
-----
10+
* https://youtu.be/oDhu5uGq_ic
11+
12+
Complexity
13+
----------
14+
15+
* Space Complexity O(days * transctions)
16+
* Time Complexity: Slow Solution O (days^2 * transactions), Faster Solution O(days * transaction)
17+
"""
18+
219

320
def max_profit(prices, K):
4-
if K == 0 or len(prices) == 0:
21+
if K == 0 or prices == []:
522
return 0
623

7-
T = [[0 for x in range(len(prices))] for y in range(K+1)]
24+
days = len(prices)
25+
num_transactions = K + 1 # 0th transaction up to and including kth transaction is considered.
26+
27+
T = [[0 for _ in range(days)] for _ in range(num_transactions)]
28+
29+
for transaction in range(1, num_transactions):
30+
max_diff = - prices[0]
31+
for day in range(1, days):
32+
T[transaction][day] = max(T[transaction][day - 1], # No transaction
33+
prices[day] + max_diff) # price on that day with max diff
34+
max_diff = max(max_diff,
35+
T[transaction - 1][day] - prices[day]) # update max_diff
836

9-
for i in range(1, len(T)):
10-
max_diff = -prices[0]
11-
for j in range(1, len(T[0])):
12-
T[i][j] = max(T[i][j-1], prices[j] + max_diff)
13-
max_diff = max(max_diff, T[i-1][j] - prices[j])
14-
1537
print_actual_solution(T, prices)
16-
return T[K][len(prices) -1]
38+
39+
return T[-1][-1]
40+
1741

1842
def max_profit_slow_solution(prices, K):
19-
if K == 0 or len(prices) == 0:
43+
if K == 0 or prices == []:
2044
return 0
2145

22-
T = [[0 for x in range(len(prices))] for y in range(K+1)]
46+
days = len(prices)
47+
num_transactions = K + 1
48+
49+
T = [[0 for _ in range(len(prices))] for _ in range(num_transactions)]
2350

24-
for i in range(1, len(T)):
25-
for j in range(1, len(T[0])):
26-
max_val = 0
27-
for m in range(0, j):
28-
max_val = max(max_val, prices[j] - prices[m] + T[i-1][m])
29-
T[i][j] = max(T[i][j-1], max_val)
51+
for transaction in range(1, num_transactions):
52+
for day in range(1, days):
53+
# This maximum value of either
54+
# a) No Transaction on the day. We pick the value from day - 1
55+
# b) Max profit made by selling on the day plus the cost of the previous transaction, considered over m days
56+
T[transaction][day] = max(T[transaction][day - 1],
57+
max([(prices[day] - prices[m] + T[transaction - 1][m]) for m in range(day)]))
3058

3159
print_actual_solution(T, prices)
32-
return T[K][len(prices) -1]
33-
60+
return T[-1][-1]
61+
3462

3563
def print_actual_solution(T, prices):
36-
i = len(T) - 1
37-
j = len(T[0]) - 1
64+
transaction = len(T) - 1
65+
day = len(T[0]) - 1
3866
stack = []
67+
3968
while True:
40-
if i == 0 or j == 0:
41-
break;
42-
if T[i][j] == T[i][j-1]:
43-
j = j - 1
69+
if transaction == 0 or day == 0:
70+
break
71+
72+
if T[transaction][day] == T[transaction][day - 1]: # Didn't sell
73+
day -= 1
4474
else:
45-
stack.append(j)
46-
max_diff = T[i][j] - prices[j]
47-
for k in range(j-1, -1, -1):
48-
if T[i-1][k] - prices[k] == max_diff:
49-
i = i - 1
50-
j = k
51-
stack.append(j)
75+
stack.append(day) # sold
76+
max_diff = T[transaction][day] - prices[day]
77+
for k in range(day - 1, -1, -1):
78+
if T[transaction - 1][k] - prices[k] == max_diff:
79+
stack.append(k) # bought
80+
transaction -= 1
5281
break
53-
54-
for i in range(len(stack)-1, -1, -2):
55-
print("Buy at price " + str(prices[stack[i]]))
56-
print("Sell at price" + str(prices[stack[i-1]]))
57-
58-
82+
83+
for entry in range(len(stack) - 1, -1, -2):
84+
print("Buy on day {day} at price {price}".format(day=stack[entry], price=prices[stack[transaction]]))
85+
print("Sell on day {day} at price {price}".format(day=stack[entry], price=prices[stack[transaction - 1]]))
86+
5987

6088
if __name__ == '__main__':
6189
prices = [2, 5, 7, 1, 4, 3, 1, 3]
62-
print(max_profit(prices, 3))
63-
print(max_profit_slow_solution(prices, 3))
64-
90+
assert 10 == max_profit(prices, 3)
91+
assert 10 == max_profit_slow_solution(prices, 3)

0 commit comments

Comments
 (0)