# Best Time to Buy and Sell Stock

• Difficulty Level : Hard
• Last Updated : 05 May, 2022

Type I: At most one transaction is allowed

Given an array price[] of length N, representing the prices of the stocks on different days, the task is to find the maximum profit possible for buying and selling the stocks on different days using transactions where at most one transaction is allowed.

Note: Stock must be bought before being sold.

Examples:

Input: prices[] = {7, 1, 5, 3, 6, 4]
Output: 5
Explanation:
The lowest price of the stock is on the 2nd day, i.e. price = 1. Starting from the 2nd day, the highest price of the stock is witnessed on the 5th day, i.e. price = 6.
Therefore, maximum possible profit = 6 – 1 = 5.

Input: prices[] = {7, 6, 4, 3, 1}
Output: 0
Explanation: Since the array is in decreasing order, no possible way exists to solve the problem.

Approach 1:
This problem can be solved using greedy approach. To maximise the profit we have to minimise the buy cost and we have to sell it on maximum price.
Follow the steps below to implement the above idea:

• Declare a buy variable to store the buy cost and max_profit to store the maximum profit.
• Initialize the buy variable to first element of profit array.
• Iterate over the prices array and check if the current price is miminum or not.
• If the current price is minimum then buy on this ith day.
• If the current price is greater then previous buy then make profit from it and maximise the max_profit.
• Finally return the max_profit.

Below is the implementation of the above approach:

## C++

 `// C++ code for the above approach``#include ``using` `namespace` `std;` `int` `maxProfit(``int` `prices[], ``int` `n)``{``    ``int` `buy = prices, max_profit = 0;``    ``for` `(``int` `i = 1; i < n; i++) {` `        ``// Checking for lower buy value``        ``if` `(buy > prices[i])``            ``buy = prices[i];` `        ``// Checking for higher profit``        ``else` `if` `(prices[i] - buy > max_profit)``            ``max_profit = prices[i] - buy;``    ``}``    ``return` `max_profit;``}` `// Driver Code``int` `main()``{``    ``int` `prices[] = { 7, 1, 5, 6, 4 };``    ``int` `n = ``sizeof``(prices) / ``sizeof``(prices);``    ``int` `max_profit = maxProfit(prices, n);``    ``cout << max_profit << endl;``    ``return` `0;``}`

Output :

`5`

Time Complexity: O(N). Where N is the size of prices array.
Auxiliary Space: O(1). We do not use any extra space.

Approach 2: The given problem can be solved based on the idea of finding the maximum difference between two array elements with smaller number occurring before the larger number. Therefore, this problem can be reduced to finding max⁡(prices[j]−prices[i]) for every pair of indices i and j, such that j>i.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach` `#include ``#include ``using` `namespace` `std;` `// Function to find maximum profit possible``// by buying and selling at most one stack``int` `findMaximumProfit(vector<``int``>& prices, ``int` `i, ``int` `k,``                      ``bool` `buy, vector >& v)``{``    ``// If no stock can be chosen``    ``if` `(i >= prices.size() || k <= 0)``        ``return` `0;` `    ``if` `(v[i][buy] != -1)``        ``return` `v[i][buy];` `    ``// If a stock is already bought``    ``if` `(buy) {``        ``return` `v[i][buy]``               ``= max(-prices[i]``                         ``+ findMaximumProfit(prices, i + 1,``                                             ``k, !buy, v),``                     ``findMaximumProfit(prices, i + 1, k,``                                       ``buy, v));``    ``}` `    ``// Otherwise``    ``else` `{``        ``// Buy now``        ``return` `v[i][buy]``               ``= max(prices[i]``                         ``+ findMaximumProfit(``                             ``prices, i + 1, k - 1, !buy, v),``                     ``findMaximumProfit(prices, i + 1, k,``                                       ``buy, v));``    ``}``}` `// Function to find the maximum``// profit in the buy and sell stock``int` `maxProfit(vector<``int``>& prices)``{` `    ``int` `n = prices.size();``    ``vector > v(n, vector<``int``>(2, -1));` `    ``// buy = 1 because atmost one``    ``// transaction is allowed``    ``return` `findMaximumProfit(prices, 0, 1, 1, v);``}` `// Driver Code``int` `main()``{``    ``// Given prices``    ``vector<``int``> prices = { 7, 1, 5, 3, 6, 4 };` `    ``// Function Call to find the``    ``// maximum profit possible by``    ``// buying and selling a single stock``    ``int` `ans = maxProfit(prices);` `    ``// Print answer``    ``cout << ans << endl;` `    ``return` `0;``}`

## Java

 `// Java code for the above approach``import` `java.util.*;` `class` `GFG {` `    ``// Function to find maximum profit possible``    ``// by buying and selling at most one stack``    ``static` `int` `findMaximumProfit(``int``[] prices, ``int` `i, ``int` `k,``                                 ``int` `buy, ``int``[][] v)``    ``{` `        ``// If no stock can be chosen``        ``if` `(i >= prices.length || k <= ``0``)``            ``return` `0``;` `        ``if` `(v[i][buy] != -``1``)``            ``return` `v[i][buy];` `        ``// If a stock is already bought``        ``// Buy now``        ``int` `nbuy;``        ``if` `(buy == ``1``)``            ``nbuy = ``0``;``        ``else``            ``nbuy = ``1``;``        ``if` `(buy == ``1``) {``            ``return` `v[i][buy] = Math.max(``                       ``-prices[i]``                           ``+ findMaximumProfit(``                               ``prices, i + ``1``, k, nbuy, v),``                       ``findMaximumProfit(prices, i + ``1``, k,``                                         ``(``int``)(buy), v));``        ``}` `        ``// Otherwise``        ``else` `{` `            ``// Buy now``            ``if` `(buy == ``1``)``                ``nbuy = ``0``;``            ``else``                ``nbuy = ``1``;``            ``return` `v[i][buy]``                ``= Math.max(``                    ``prices[i]``                        ``+ findMaximumProfit(prices, i + ``1``,``                                            ``k - ``1``, nbuy, v),``                    ``findMaximumProfit(prices, i + ``1``, k, buy,``                                      ``v));``        ``}``    ``}` `    ``// Function to find the maximum``    ``// profit in the buy and sell stock``    ``static` `int` `maxProfit(``int``[] prices)``    ``{``        ``int` `n = prices.length;``        ``int``[][] v = ``new` `int``[n][``2``];` `        ``for` `(``int` `i = ``0``; i < v.length; i++) {``            ``v[i][``0``] = -``1``;``            ``v[i][``1``] = -``1``;``        ``}` `        ``// buy = 1 because atmost one``        ``// transaction is allowed``        ``return` `findMaximumProfit(prices, ``0``, ``1``, ``1``, v);``    ``}` `    ``// Driver Code``    ``public` `static` `void` `main(String[] args)``    ``{` `        ``// Given prices``        ``int``[] prices = { ``7``, ``1``, ``5``, ``3``, ``6``, ``4` `};` `        ``// Function Call to find the``        ``// maximum profit possible by``        ``// buying and selling a single stock``        ``int` `ans = maxProfit(prices);` `        ``// Print answer``        ``System.out.println(ans);``    ``}` `    ``// This code is contributed by Potta Lokesh`

## Python3

 `# Python 3 program for the above approach`  `# Function to find maximum profit possible``# by buying and selling at most one stack``def` `findMaximumProfit(prices, i,  k,``                      ``buy, v):` `    ``# If no stock can be chosen``    ``if` `(i >``=` `len``(prices) ``or` `k <``=` `0``):``        ``return` `0` `    ``if` `(v[i][buy] !``=` `-``1``):``        ``return` `v[i][buy]` `    ``# If a stock is already bought``    ``if` `(buy):``        ``v[i][buy] ``=` `max``(``-``prices[i]``                        ``+` `findMaximumProfit(prices, i ``+` `1``,``                                            ``k, ``not` `buy, v),``                        ``findMaximumProfit(prices, i ``+` `1``, k,``                                          ``buy, v))``        ``return` `v[i][buy]` `    ``# Otherwise``    ``else``:``        ``# Buy now``        ``v[i][buy] ``=` `max``(prices[i]``                        ``+` `findMaximumProfit(``            ``prices, i ``+` `1``, k ``-` `1``, ``not` `buy, v),``            ``findMaximumProfit(prices, i ``+` `1``, k,``                              ``buy, v))``        ``return` `v[i][buy]`  `# Function to find the maximum``# profit in the buy and sell stock``def` `maxProfit(prices):` `    ``n ``=` `len``(prices)``    ``v ``=` `[[``-``1` `for` `x ``in` `range``(``2``)]``for` `y ``in` `range``(n)]` `    ``# buy = 1 because atmost one``    ``# transaction is allowed``    ``return` `findMaximumProfit(prices, ``0``, ``1``, ``1``, v)`  `# Driver Code``if` `__name__ ``=``=` `"__main__"``:` `    ``# Given prices``    ``prices ``=` `[``7``, ``1``, ``5``, ``3``, ``6``, ``4``]` `    ``# Function Call to find the``    ``# maximum profit possible by``    ``# buying and selling a single stock``    ``ans ``=` `maxProfit(prices)` `    ``# Print answer``    ``print``(ans)`

## C#

 `// C# program for above approach``using` `System;` `class` `GFG {` `    ``// Function to find maximum profit possible``    ``// by buying and selling at most one stack``    ``static` `int` `findMaximumProfit(``int``[] prices, ``int` `i, ``int` `k,``                                 ``int` `buy, ``int``[, ] v)``    ``{` `        ``// If no stock can be chosen``        ``if` `(i >= prices.Length || k <= 0)``            ``return` `0;` `        ``if` `(v[i, buy] != -1)``            ``return` `v[i, buy];` `        ``// If a stock is already bought``        ``// Buy now``        ``int` `nbuy;``        ``if` `(buy == 1)``            ``nbuy = 0;``        ``else``            ``nbuy = 1;``        ``if` `(buy == 1) {``            ``return` `v[i, buy] = Math.Max(``                       ``-prices[i]``                           ``+ findMaximumProfit(``                               ``prices, i + 1, k, nbuy, v),``                       ``findMaximumProfit(prices, i + 1, k,``                                         ``(``int``)(buy), v));``        ``}` `        ``// Otherwise``        ``else` `{` `            ``// Buy now``            ``if` `(buy == 1)``                ``nbuy = 0;``            ``else``                ``nbuy = 1;``            ``return` `v[i, buy]``                ``= Math.Max(``                    ``prices[i]``                        ``+ findMaximumProfit(prices, i + 1,``                                            ``k - 1, nbuy, v),``                    ``findMaximumProfit(prices, i + 1, k, buy,``                                      ``v));``        ``}``    ``}` `    ``// Function to find the maximum``    ``// profit in the buy and sell stock``    ``static` `int` `maxProfit(``int``[] prices)``    ``{``        ``int` `n = prices.Length;``        ``int``[, ] v = ``new` `int``[n, 2];` `        ``for` `(``int` `i = 0; i < n; i++) {``            ``v[i, 0] = -1;``            ``v[i, 1] = -1;``        ``}` `        ``// buy = 1 because atmost one``        ``// transaction is allowed``        ``return` `findMaximumProfit(prices, 0, 1, 1, v);``    ``}` `    ``// Driver Code``    ``public` `static` `void` `Main()``    ``{` `        ``// Given prices``        ``int``[] prices = { 7, 1, 5, 3, 6, 4 };` `        ``// Function Call to find the``        ``// maximum profit possible by``        ``// buying and selling a single stock``        ``int` `ans = maxProfit(prices);` `        ``// Print answer``        ``Console.Write(ans);``    ``}``}` `// This code is contributed by Samim Hossain Mondal.`

## Javascript

 ``
Output
`5`

Time complexity: O(N) where N is the length of the given array.
Auxiliary Space: O(N)

Type II: Infinite transactions are allowed

Given an array price[] of length N, representing the prices of the stocks on different days, the task is to find the maximum profit possible for buying and selling the stocks on different days using transactions where any number of transactions are allowed.

Examples:

Input: prices[] = {7, 1, 5, 3, 6, 4}
Output: 7
Explanation:
Purchase on 2nd day. Price = 1.
Sell on 3rd day. Price = 5.
Therefore, profit = 5 – 1 = 4.
Purchase on 4th day. Price = 3.
Sell on 5th day. Price = 6.
Therefore, profit = 4 + (6 – 3) = 7.

Input: prices = {1, 2, 3, 4, 5}
Output: 4
Explanation:
Purchase on 1st day. Price = 1.
Sell on 5th day. Price = 5.
Therefore, profit = 5 – 1 = 4.

Approach: The idea is to maintain a boolean value that denotes if there is any current purchase ongoing or not. If yes, then at the current state, the stock can be sold to maximize profit or move to the next price without selling the stock. Otherwise, if no transaction is happening, the current stock can be bought or move to the next price without buying.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// Function to calculate maximum``// profit possible by buying or``// selling stocks any number of times``int` `find(``int` `ind, vector<``int``>& v, ``bool` `buy,``         ``vector >& memo)``{` `    ``// No prices left``    ``if` `(ind >= v.size())``        ``return` `0;` `    ``// Already found``    ``if` `(memo[ind][buy] != -1)``        ``return` `memo[ind][buy];` `    ``// Already bought, now sell``    ``if` `(buy) {``        ``return` `memo[ind][buy]``               ``= max(-v[ind] + find(ind + 1, v, !buy, memo),``                     ``find(ind + 1, v, buy, memo));``    ``}` `    ``// Otherwise, buy the stock``    ``else` `{``        ``return` `memo[ind][buy]``               ``= max(v[ind] + find(ind + 1, v, !buy, memo),``                     ``find(ind + 1, v, buy, memo));``    ``}``}` `// Function to find the maximum``// profit possible by buying and``// selling stocks any number of times``int` `maxProfit(vector<``int``>& prices)``{``    ``int` `n = prices.size();``    ``if` `(n < 2)``        ``return` `0;` `    ``vector > v(n + 1, vector<``int``>(2, -1));``    ``return` `find(0, prices, 1, v);``}` `// Driver Code``int` `main()``{` `    ``// Given prices``    ``vector<``int``> prices = { 7, 1, 5, 3, 6, 4 };` `    ``// Function Call to calculate``    ``// maximum profit possible``    ``int` `ans = maxProfit(prices);` `    ``// Print the total profit``    ``cout << ans << endl;``    ``return` `0;``}`
Output
`7`

Time complexity: O(N) where N is the length of the given array.
Auxiliary Space: O(N)

Type III: At most two transactions are allowed

Problem: Given an array price[] of length N which denotes the prices of the stocks on different days. The task is to find the maximum profit possible for buying and selling the stocks on different days using transactions where at most two transactions are allowed.

Note: Stock must be bought before being sold.

Input: prices[] = {3, 3, 5, 0, 0, 3, 1, 4}
Output:
Explanation:
Buy on Day 4 and Sell at Day 6 => Profit = 3 0 = 3
Buy on Day 7 and Sell at Day 8 => Profit = 4 1 = 3
Therefore, Total Profit = 3 + 3 = 6

Input: prices[] = {1, 2, 3, 4, 5}
Output:
Explanation:
Buy on Day 1 and sell at Day 6 => Profit = 5 1 = 4
Therefore, Total Profit = 4

Approach: The problem can be solved by following the above approach. Now, if the number of transactions is equal to 2, then the current profit can be the desired answer. Similarly, Try out all the possible answers by memoizing them into the DP Table.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach` `#include ``#include ``using` `namespace` `std;` `// Function to find the maximum``// profit in the buy and sell stock``int` `find(vector<``int``>& prices, ``int` `ind, ``bool` `buy, ``int` `c,``         ``vector > >& memo)``{``    ``// If buy =1 means buy now``    ``// else sell``    ``if` `(ind >= prices.size() || c >= 2)``        ``return` `0;``    ``if` `(memo[ind][buy] != -1)``        ``return` `memo[ind][buy];` `    ``// Already bought, sell now``    ``if` `(buy) {``        ``return` `memo[ind][buy]``               ``= max(-prices[ind]``                         ``+ find(prices, ind + 1, !buy, c,``                                ``memo),``                     ``find(prices, ind + 1, buy, c, memo));``    ``}` `    ``// Can buy stocks``    ``else` `{``        ``return` `memo[ind][buy]``               ``= max(prices[ind]``                         ``+ find(prices, ind + 1, !buy,``                                ``c + 1, memo),``                     ``find(prices, ind + 1, buy, c, memo));``    ``}``}` `// Function to find the maximum``// profit in the buy and sell stock``int` `maxProfit(vector<``int``>& prices)``{``    ``// Here maximum two transaction are allowed` `    ``// Use 3-D vector because here``    ``// three states are there: i,k,buy/sell``    ``vector > > memo(``        ``prices.size(),``        ``vector >(2, vector<``int``>(2, -1)));` `    ``// Answer``    ``return` `find(prices, 0, 1, 0, memo);``}` `// Driver Code``int` `main()``{` `    ``// Given prices``    ``vector<``int``> prices = { 3, 3, 5, 0, 0, 3, 1, 4 };` `    ``// Function Call``    ``int` `ans = maxProfit(prices);` `    ``// Answer``    ``cout << ans << endl;``    ``return` `0;``}`
Output
`6`

Time complexity: O(N), where N is the length of the given array.
Auxiliary Space: O(N)

Type IV: At most K transactions are allowed

Problem: Given an array price[] of length N which denotes the prices of the stocks on different days. The task is to find the maximum profit possible for buying and selling the stocks on different days using transactions where at most K transactions are allowed.

Note: Stock must be bought before being sold.

Examples:

Input: K = 2, prices[] = {2, 4, 1}
Output: 2
Explanation: Buy on day 1 when price is 2 and sell on day 2 when price is 4. Therefore, profit = 4-2 = 2.

Input: K = 2, prices[] = {3, 2, 6, 5, 0, 3}
Output: 7
Explanation:
Buy on day 2 when price is 2 and sell on day 3 when price is 6. Therefore, profit = 6-2 = 4.
Buy on day 5 when price is 0 and sell on day 6 when price is 3. Therefore, profit = 3-0 = 3.
Therefore, the total profit = 4+3 = 7

Approach: The idea is to maintain the count of transactions completed till and compare the count of the transaction to K. If it is less than K then buy and sell the stock. Otherwise, the current profit can be the maximum profit.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach` `#include ``#include ``using` `namespace` `std;` `// Function to find the maximum``// profit with atmost K transactions``int` `find(vector<``int``>& prices, ``int` `ind, ``bool` `buy, ``int` `c,``         ``int` `k, vector > >& memo)``{` `    ``// If there are no more transaction``    ``// allowed, return the profit as 0``    ``if` `(ind >= prices.size() || c >= k)``        ``return` `0;` `    ``// Memoize``    ``else` `if` `(memo[ind][buy] != -1)``        ``return` `memo[ind][buy];` `    ``// Already bought, now sell``    ``if` `(buy) {``        ``return` `memo[ind][buy] = max(``                   ``-prices[ind]``                       ``+ find(prices, ind + 1, !buy, c, k,``                              ``memo),``                   ``find(prices, ind + 1, buy, c, k, memo));``    ``}` `    ``// Stocks can be bought``    ``else` `{``        ``return` `memo[ind][buy] = max(``                   ``prices[ind]``                       ``+ find(prices, ind + 1, !buy, c + 1,``                              ``k, memo),``                   ``find(prices, ind + 1, buy, c, k, memo));``    ``}``}` `// Function to find the maximum profit``// in the buy and sell stock``int` `maxProfit(``int` `k, vector<``int``>& prices)``{``    ``// If transactions are greater``    ``// than number of prices``    ``if` `(2 * k > prices.size()) {``        ``int` `res = 0;``        ``for` `(``int` `i = 1; i < prices.size(); i++) {``            ``res += max(0, prices[i] - prices[i - 1]);``        ``}``        ``return` `res;``    ``}` `    ``// Maximum k transaction``    ``vector > > memo(``        ``prices.size() + 1,``        ``vector >(2, vector<``int``>(k + 1, -1)));``    ``return` `find(prices, 0, 1, 0, k, memo);``}` `// Driver Code``int` `main()``{` `    ``// Given prices``    ``vector<``int``> prices = { 2, 4, 1 };` `    ``// Given K``    ``int` `k = 2;` `    ``// Function Call``    ``int` `ans = maxProfit(k, prices);` `    ``// Print answer``    ``cout << ans << endl;``    ``return` `0;``}`
Output
`2`

Time complexity: O(N*K), where N is the length of the given array and K is the number of transactions allowed.
Auxiliary Space: O(N*K)

My Personal Notes arrow_drop_up