Given a list containing future predictions of share prices, find the maximum profit earned by buying and selling shares at most k times with a constraint that a new transaction can only start after the previous transaction is complete, i.e., we can only hold at most one share at a time.

For example,

 
Input:
Stock Price: {2, 4, 7, 5, 4, 3, 5}
k = 2
 
Output: The maximum profit is 7 (sum of 5 and 2)
 
Buy at a price 2 and sell at a price 7
Buy at a price 3 and sell at a price 5
 
 
Input:
Stock Price: {1, 5, 2, 3, 7, 6, 4, 5}
k = 3
 
Output: The maximum profit is 10 (sum of 4, 5 and 1)
 
Buy at a price 1 and sell at a price 5
Buy at a price 2 and sell at a price 7
Buy at a price 4 and sell at a price 5
 
 
Input:
Stock Price: {10, 6, 8, 4, 2}
k = 2
 
Output: The maximum profit is 2
 
Buy at a price 6 and sell at a price 8
 
 
Input:
Stock Price: {10, 8, 6, 5, 4, 2}
k = 1
 
Output: The maximum profit is 0

Practice this problem

There are several variations to the above problem:

  1. If we are allowed to stock only once, then we can find the maximum difference between two elements in the array, where the smaller element appears before the larger element.
  2. If we are allowed to stock shares at most twice, we can follow the approach discussed here.
  3. If we are allowed to stock shares any number of times, we can follow the approach discussed here.

Now we are only allowed to make at most k stock transactions. We can solve the problem by using dynamic programming. Let T[t][i] be the maximum profit using most t transactions till the i'th day. Then T[i] can be written as:

T[t][i] = max(T[t][i-1], max(price[i] – price[j] + T[t-1][j]))
                            where j varies from 0 to i-1

The above relation states that T[t][i] would be a maximum of below:

  1. T[t][i-1], which represents not doing any transaction on the i'th day.
  2. Maximum profit gained by selling on the i'th day. To sell shares on the i'th day, we need to purchase them on any previous day. If we buy shares on the j'th day and sell it on the i'th day, the maximum profit will be price[i] - price[j] + T[t-1][j], where j varies from 0 to i-1 and T[t-1][j] is the best with one less transaction till the j'th day.

The algorithm can be implemented as follows in C++, Java, and Python:

C++


Download  Run Code

Output:

The maximum possible profit is 10

Java


Download  Run Code

Output:

The maximum possible profit is 10

Python


Download  Run Code

Output:

The maximum possible profit is 10

The time complexity of the above solution is O(n2k) and requires O(n.k) extra space, where n is the total number of given days and k is the maximum number of allowed stock transactions. We can easily optimize the code to run in O(n.k) time if we can calculate the maximum profit gained by selling shares on the i'th day in constant time.

Optimized Solution

We have already seen that T[i] can be written as:

T[t][i] = max(T[t][i-1], max(price[i] – price[j] + T[t-1][j]))
                            where j varies from 0 to i-1

If we carefully notice, max(price[i] - price[j] + T[t-1][j]) can be rewritten as,

= price[i] + max(T[t-1][j] – price[j]), where j varies from 0 to i-1
 
= price[i] + max(prev_diff, T[t-1][i-1] – price[i-1])
  where prev_diff is max(T[t-1][j] – price[j]) and j varies from 0 to i-2

Since we have already calculated max(T[t-1][j] - price[j]) for every j within range [0, i-2], we can easily calculate it for j=i-1 in O(1) time. In other words, we don’t have to revisit range [0, i-1] to figure out the best day for buying stock. This can be determined in O(1) time using the following revised relation:

T[t][i] = max(T[t][i-1], price[i] + max(prev_diff, T[t-1][i-1] – price[i-1]))
           where prev_diff is max(T[t-1][j] – price[j]) and j varies from 0 to i-2

The algorithm can be implemented as follows in C++, Java, and Python:

C++


Download  Run Code

Output:

The maximum possible profit is 10

Java


Download  Run Code

Output:

The maximum possible profit is 10

Python


Download  Run Code

Output:

The maximum possible profit is 10

The time complexity of the above solution is O(n.k) and requires O(n.k) extra space, where n is the total number of given days and k is the maximum number of allowed stock transactions. The space complexity can be further reduced to O(n) since we only need results from the last transaction.

 
Author: Aditya Goel