 GFG App
Open App Browser
Continue

Type I: At most one transaction is allowed

Given an array prices[] 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 the greedy approach. To maximize the profit we have to minimize the buy cost and we have to sell it at 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 the first element of the prices array.
• Iterate over the prices array and check if the current price is minimum or not.
• If the current price is minimum then buy on this ith day.
• If the current price is greater than the previous buy then make profit from it and maximize 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;` `}`

## Java

 `// Java code for the above approach` `class` `GFG {` `    ``static` `int` `maxProfit(``int` `prices[], ``int` `n)` `    ``{` `        ``int` `buy = prices[``0``], 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` `    ``public` `static` `void` `main(String args[])` `    ``{` `        ``int` `prices[] = { ``7``, ``1``, ``5``, ``6``, ``4` `};` `        ``int` `n = prices.length;` `        ``int` `max_profit = maxProfit(prices, n);` `        ``System.out.println(max_profit);` `    ``}` `}`   `// This code is contributed by Lovely Jain`

## Python3

 `# Python program for the above approach:`     `def` `maxProfit(prices, n):` `    ``buy ``=` `prices[``0``]` `    ``max_profit ``=` `0` `    ``for` `i ``in` `range``(``1``, n):`   `        ``# Checking for lower buy value` `        ``if` `(buy > prices[i]):` `            ``buy ``=` `prices[i]`   `        ``# Checking for higher profit` `        ``elif` `(prices[i] ``-` `buy > max_profit):` `            ``max_profit ``=` `prices[i] ``-` `buy` `    ``return` `max_profit`     `# Driver code` `if` `__name__ ``=``=` `'__main__'``:`   `    ``prices ``=` `[``7``, ``1``, ``5``, ``6``, ``4``]` `    ``n ``=` `len``(prices)` `    ``max_profit ``=` `maxProfit(prices, n)` `    ``print``(max_profit)`

## C#

 `// C# code for the above approach` `using` `System;` `public` `class` `GFG {`   `    ``static` `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;` `    ``}`   `    ``static` `public` `void` `Main()` `    ``{`   `        ``// Code` `        ``int``[] prices = { 7, 1, 5, 6, 4 };` `        ``int` `n = prices.Length;` `        ``int` `max_profit = maxProfit(prices, n);` `        ``Console.WriteLine(max_profit);` `    ``}` `}`   `// This code is contributed by lokeshmvs21.`

## Javascript

 `function` `maxProfit( prices, n)` `{` `    ``let buy = prices, max_profit = 0;` `    ``for` `(let 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`   `    ``let prices= [ 7, 1, 5, 6, 4 ];` `    ``let n =5;` `    ``let max_profit = maxProfit(prices, n);` `    ``console.log(max_profit);` `    `  `    ``// This code is contributed by garg28harsh.`

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)

Approach3: (Iterative version of DP approach)

The approach is to use a 2D DP array to store the maximum profit that can be obtained on each day, with either 0 or 1 stocks. The base case is set for the first day, with -prices stored in dp to represent the maximum profit that can be obtained by buying a stock on the first day, and 0 stored in dp to represent the maximum profit that can be obtained by selling a stock on the first day.

Then, for each subsequent day i, there are two choices:

•    Buy the stock at i, in which case the profit we get is the maximum profit we could have made till i-1 minus the price at i.        This is represented by the equation dp[i] = max(dp[i-1], -prices[i]).
•    Sell the stock at i, in which case the profit we get is the maximum profit we could have made till i-1 by buying the stock        earlier plus the price at i. This is represented by the equation dp[i] = max(dp[i-1], dp[i-1] + prices[i]).

The maximum profit calculated from the last day is returned as the final result.

Algorithm:

1.    Initialize a 2D DP array with n rows and 2 columns, where n is the size of the prices vector.
2.    Initialize the first row of the DP array as follows:
•  dp = -prices, since the only way to have a negative profit on day 0 is by buying the stock at its current price.
•  dp = 0, since it is not possible to make a profit by selling the stock on day 0.
3.    Loop through the prices vector from index 1 to n-1 and for each index i, do the following:
•  dp[i] = max(dp[i-1], -prices[i]), since we have a choice of buying the stock at its current price, in which case we should buy it  only if the maximum profit we could have made until the previous day minus the price at index i is greater than the maximum profit  we could have made until the previous day by not buying the stock.
•  dp[i] = max(dp[i-1], dp[i-1] + prices[i]), since we have a choice of selling the stock at its current price, in which case we  should sell it only if the maximum profit we could have made until the previous day by buying the stock earlier plus the price at  index i is greater than the maximum profit we could have made until the previous day by not selling the stock.
4.    Return the maximum of dp[n-1] and dp[n-1], since the maximum profit we could have made on the last day is either by selling the        stock or not buying the stock at all.

Below is the implementation of the approach:

## C++

 `// C++ code for the approach`   `#include ` `using` `namespace` `std;`   `// Function to find the maximum` `// profit with atmost 1 transaction` `int` `maxProfit(vector<``int``>& prices)` `{` `    ``int` `n = prices.size();`   `    ``// 2D DP array to store max profit with 0 and 1 stocks` `    ``vector > dp(n, vector<``int``>(2));`   `    ``dp = -prices;` `    ``dp = 0;`   `    ``// Loop through prices to calculate max profit at each` `    ``// day` `    ``for` `(``int` `i = 1; i < n; i++) {` `        ``// choice 1: Buy the stock at i, in which case the` `        ``// profit we get is the maximum profit we could have` `        ``// made till i-1 minus the price at i.` `        ``dp[i] = max(dp[i - 1], -prices[i]);`   `        ``// choice 2:Sell the stock at i, in which case the` `        ``// profit we get is the maximum profit we could have` `        ``// made till i-1 by buying the stock earlier plus` `        ``// the price at i.` `        ``dp[i]` `            ``= max(dp[i - 1], dp[i - 1] + prices[i]);` `    ``}`   `    ``// Return the maximum profit calculated from the last` `    ``// day` `    ``return` `max(dp.back(), dp.back());` `}`   `// Driver's code` `int` `main()` `{` `    ``// Given prices` `    ``vector<``int``> prices = { 7, 1, 5, 3, 6, 4 };`   `    ``// Function Call` `    ``int` `ans = maxProfit(prices);`   `    ``// Print answer` `    ``cout << ans << endl;` `    ``return` `0;` `}`

Output

`5`

Time complexity: O(N) where N is the length of the given array. This is because we are iterating from 1 to N.
Auxiliary Space: O(N) as we are creating a 2D DP array but columns are only 2 so we can ignore those in complexity analysis which consequently results is counting complexity for rows only. Here, N is size of the input array.

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;` `}`

## 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` `maxProfit(``int``[] prices)` `    ``{` `        ``int` `n = prices.length;` `        ``int``[][] dp = ``new` `int``[n][``2``];` `        ``for` `(``int``[] row : dp)` `            ``Arrays.fill(row, -``1``);` `        ``return` `findMaximumProfit(``0``, ``1``, prices, dp);` `    ``}` `    ``static` `int` `findMaximumProfit(``int` `i, ``int` `k, ``int``[] prices,` `                                 ``int``[][] dp)` `    ``{`   `        ``if` `(i == prices.length)` `            ``return` `0``;` `        ``if` `(dp[i][k] != -``1``)` `            ``return` `dp[i][k];` `        ``int` `profit = ``0``;` `        ``if` `(k == ``1``) {` `            ``int` `buy` `                ``= -prices[i]` `                  ``+ findMaximumProfit(i + ``1``, ``0``, prices, dp);` `            ``int` `notBuy` `                ``= findMaximumProfit(i + ``1``, ``1``, prices, dp);` `            ``profit = Math.max(buy, notBuy);` `        ``}` `        ``else` `{` `            ``int` `sell` `                ``= prices[i]` `                  ``+ findMaximumProfit(i + ``1``, ``1``, prices, dp);` `            ``int` `notSell` `                ``= findMaximumProfit(i + ``1``, ``0``, prices, dp);` `            ``profit = Math.max(sell, notSell);` `        ``}`   `        ``return` `dp[i][k] = profit;` `    ``}` `    ``// Driver Code` `    ``public` `static` `void` `main(String[] args)` `    ``{`   `        ``// Given prices` `        ``int``[] prices = { ``7``, ``1``, ``5``, ``3``, ``6``, ``4` `};` `        ``int` `ans = maxProfit(prices);`   `        ``// Print answer` `        ``System.out.println(ans);` `    ``}` `}`

## Python3

 `# Python program for the above approach`   `# Function to calculate maximum` `# profit possible by buying or` `# selling stocks any number of times`     `def` `find(ind, v, buy, memo):`   `    ``# No prices left` `    ``if` `ind >``=` `len``(v):` `        ``return` `0`   `    ``# Already found` `    ``if` `(memo[ind][buy] !``=` `-``1``):` `        ``return` `memo[ind][buy]`   `    ``# Already bought, now sell` `    ``if` `(buy):`   `        ``memo[ind][buy] ``=` `max``(``-``v[ind] ``+` `find(ind ``+` `1``, v,` `                                            ``not` `buy, memo), find(ind ``+` `1``, v, buy, memo))` `        ``return` `memo[ind][buy]`   `    ``# Otherwise, buy the stock` `    ``else``:` `        ``memo[ind][buy] ``=` `max``(` `            ``v[ind] ``+` `find(ind ``+` `1``, v, ``not` `buy, memo), find(ind ``+` `1``, v, buy, memo))` `        ``return` `memo[ind][buy]`   `# Function to find the maximum` `# profit possible by buying and` `# selling stocks any number of times`     `def` `maxProfit(prices):` `    ``n ``=` `len``(prices)`   `    ``if` `(n < ``2``):` `        ``return` `0` `    ``v ``=` `[[``-``1` `for` `i ``in` `range``(``2``)]``for` `j ``in` `range``(n``+``1``)]`   `    ``return` `find(``0``, prices, ``1``, v)`     `# Driver Code`     `# Given prices` `prices ``=` `[``7``, ``1``, ``5``, ``3``, ``6``, ``4``]`   `# Function Call to calculate` `# maximum profit possible` `ans ``=` `maxProfit(prices)`   `# Print the total profit` `print``(ans)`   `# This Code is Contributed By Vivek Maddeshiya`

## C#

 `// C# code for the above approach`   `using` `System;`   `public` `class` `GFG {`   `    ``// Function to find maximum profit possible` `    ``// by buying and selling at most one stack` `    ``static` `int` `maxProfit(``int``[] prices)` `    ``{` `        ``int` `n = prices.Length;` `        ``int``[, ] dp = ``new` `int``[n, 2];` `        ``for` `(``int` `i = 0; i < n; i++) {` `            ``for` `(``int` `j = 0; j < 2; j++) {` `                ``dp[i, j] = -1;` `            ``}` `        ``}` `        ``return` `findMaximumProfit(0, 1, prices, dp);` `    ``}`   `    ``static` `int` `findMaximumProfit(``int` `i, ``int` `k, ``int``[] prices,` `                                 ``int``[, ] dp)` `    ``{`   `        ``if` `(i == prices.Length)` `            ``return` `0;` `        ``if` `(dp[i, k] != -1)` `            ``return` `dp[i, k];` `        ``int` `profit = 0;` `        ``if` `(k == 1) {` `            ``int` `buy` `                ``= -prices[i]` `                  ``+ findMaximumProfit(i + 1, 0, prices, dp);` `            ``int` `notBuy` `                ``= findMaximumProfit(i + 1, 1, prices, dp);` `            ``profit = Math.Max(buy, notBuy);` `        ``}` `        ``else` `{` `            ``int` `sell` `                ``= prices[i]` `                  ``+ findMaximumProfit(i + 1, 1, prices, dp);` `            ``int` `notSell` `                ``= findMaximumProfit(i + 1, 0, prices, dp);` `            ``profit = Math.Max(sell, notSell);` `        ``}`   `        ``return` `dp[i, k] = profit;` `    ``}`   `    ``static` `public` `void` `Main()` `    ``{`   `        ``// Given prices` `        ``int``[] prices = { 7, 1, 5, 3, 6, 4 };` `        ``int` `ans = maxProfit(prices);`   `        ``// Print answer` `        ``Console.WriteLine(ans);` `    ``}` `}`   `// This code is contributed by lokeshmvs21.`

## Javascript

 `// JavaScript program for the above approach`   `// Function to calculate maximum` `// profit possible by buying or` `// selling stocks any number of times` `function` `find(ind, v, buy, memo) {` `    ``// No prices left` `    ``if` `(ind >= v.length) {` `        ``return` `0;` `    ``}`   `    ``// Already found` `    ``if` `(memo[ind][buy ? 1 : 0] != -1) {` `        ``return` `memo[ind][buy ? 1 : 0];` `    ``}`   `    ``// Already bought, now sell` `    ``if` `(buy) {` `        ``return` `memo[ind][buy ? 1 : 0] = Math.max(-v[ind] + ` `        ``find(ind + 1, v, ``false``, memo), find(ind + 1, v, buy, memo));` `    ``}`   `    ``// Otherwise, buy the stock` `    ``else` `{` `        ``return` `memo[ind][buy ? 1 : 0] = Math.max(v[ind] + ` `        ``find(ind + 1, v, ``true``, memo), find(ind + 1, v, buy, memo));` `    ``}` `}`   `// Function to find the maximum` `// profit possible by buying and` `// selling stocks any number of times` `function` `maxProfit(prices) {` `    ``let n = prices.length;` `    ``if` `(n < 2) {` `        ``return` `0;` `    ``}`   `    ``let memo = Array(n).fill().map(() => Array(2).fill(-1));` `    ``return` `find(0, prices, ``true``, memo);` `}`   `// Driver code` `let prices = [7, 1, 5, 3, 6, 4];` `let ans = maxProfit(prices);` `console.log(ans);`

Output

`7`

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

Method 2 :- Optimised Solution

One more way to solve the problem is to think of the situation when we buy the stocks in the beginning of the upstreak in the stock graph and sell it at the highest point of that upstreak line of the graph. We just have to calculate the sum of all the upstreaks that are present in the graph.

Below is the implementation of the above approach:-

## C++

 `// C++ program for the above approach` `#include ` `using` `namespace` `std;`   `// 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;` `    ``int` `sellingDate = 0;` `    ``int` `buyingDate = 0;` `    ``int` `totalProfit = 0;` `    ``for` `(``int` `i = 1; i < prices.size(); i++) {` `        ``if` `(prices[i] >= prices[i - 1])` `            ``sellingDate++;` `        ``else` `{` `            ``totalProfit += (prices[sellingDate]` `                            ``- prices[buyingDate]);` `            ``sellingDate = buyingDate = i;` `        ``}` `    ``}` `    ``totalProfit` `        ``+= (prices[sellingDate] - prices[buyingDate]);` `    ``return` `totalProfit;` `}`   `// 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;` `}`   `// This code is contributed by Aditya Kumar (adityakumar129)`

## Java

 `// "static void main" must be defined in a public class.` `public` `class` `GFG {`   `    ``// Function to find the maximum profit possible by` `    ``// buying and selling stocks any number of times` `    ``static` `int` `maxProfit(``int``[] prices, ``int` `n)` `    ``{`   `        ``if` `(n < ``2``)` `            ``return` `0``;` `        ``int` `sellingDate = ``0``;` `        ``int` `buyingDate = ``0``;` `        ``int` `totalProfit = ``0``;` `        ``for` `(``int` `i = ``1``; i < n; i++) {` `            ``if` `(prices[i] >= prices[i - ``1``])` `                ``sellingDate++;` `            ``else` `{` `                ``totalProfit += (prices[sellingDate]` `                                ``- prices[buyingDate]);` `                ``sellingDate = buyingDate = i;` `            ``}` `        ``}` `        ``totalProfit` `            ``+= (prices[sellingDate] - prices[buyingDate]);` `        ``return` `totalProfit;` `    ``}`   `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``// Given prices` `        ``int``[] prices = { ``7``, ``1``, ``5``, ``3``, ``6``, ``4` `};`   `        ``// Function Call to calculate maximum profit` `        ``// possible` `        ``int` `ans = maxProfit(prices, ``6``);`   `        ``// Print the total profit` `        ``System.out.print(ans);` `    ``}` `}`   `// This code is contributed by garg28harsh.`

## Python3

 `# Python3 program for the above approach`   `# Function to find the maximum profit possible by buying` `# and selling stocks any number of times`     `def` `maxProfit(prices):`   `    ``n ``=` `len``(prices)` `    ``if` `(n < ``2``):` `        ``return` `0`   `    ``sellingDate ``=` `0` `    ``buyingDate ``=` `0` `    ``totalProfit ``=` `0` `    ``for` `i ``in` `range``(``1``, ``len``(prices)):` `        ``if` `(prices[i] >``=` `prices[i ``-` `1``]):` `            ``sellingDate ``+``=` `1` `        ``else``:` `            ``totalProfit ``+``=` `(prices[sellingDate] ``-` `prices[buyingDate])` `            ``sellingDate ``=` `buyingDate ``=` `i`   `    ``totalProfit ``+``=` `(prices[sellingDate] ``-` `prices[buyingDate])` `    ``return` `totalProfit`     `# Given prices` `prices ``=` `[``7``, ``1``, ``5``, ``3``, ``6``, ``4``]`   `# Function Call to calculate maximum profit possible` `ans ``=` `maxProfit(prices)`   `# Prthe total profit` `print``(ans)`   `# This code is contributed by akashish__`

## C#

 `using` `System;` `class` `GfG {`   `    ``// Function to find the maximum profit possible by` `    ``// buying and selling stocks any number of times` `    ``static` `int` `maxProfit(``int``[] prices)` `    ``{` `        ``int` `n = prices.Length;` `        ``if` `(n < 2)` `            ``return` `0;` `        ``int` `sellingDate = 0;` `        ``int` `buyingDate = 0;` `        ``int` `totalProfit = 0;` `        ``for` `(``int` `i = 1; i < n; i++) {` `            ``if` `(prices[i] >= prices[i - 1])` `                ``sellingDate++;` `            ``else` `{` `                ``totalProfit += (prices[sellingDate]` `                                ``- prices[buyingDate]);` `                ``sellingDate = buyingDate = i;` `            ``}` `        ``}` `        ``totalProfit` `            ``+= (prices[sellingDate] - prices[buyingDate]);` `        ``return` `totalProfit;` `    ``}` `    ``static` `void` `Main()` `    ``{` `        ``int``[] prices = { 7, 1, 5, 3, 6, 4 };`   `        ``// Function Call to calculate maximum profit` `        ``// possible` `        ``int` `ans = maxProfit(prices);`   `        ``// Print the total profit` `        ``Console.Write(ans);` `    ``}` `}`   `// This code is contributed by garg28harsh.`

## Javascript

 `// Function to find the maximum profit possible by buying` `// and selling stocks any number of times` `function` `maxProfit(prices)` `{` `    ``let n = prices.length;` `    ``if` `(n < 2)` `        ``return` `0;` `    ``let sellingDate = 0;` `    ``let buyingDate = 0;` `    ``let totalProfit = 0;` `    ``for` `(let i = 1; i < n; i++) {` `        ``if` `(prices[i] >= prices[i - 1])` `            ``sellingDate++;` `        ``else` `{` `            ``totalProfit += (prices[sellingDate] - prices[buyingDate]);` `            ``sellingDate = buyingDate = i;` `        ``}` `    ``}` `    ``totalProfit += (prices[sellingDate] - prices[buyingDate]);` `    ``return` `totalProfit;` `}`   `// Driver Code`   `    ``// Given prices` `    ``let prices = [ 7, 1, 5, 3, 6, 4 ];` `    `  `    ``// Function Call to calculate maximum profit possible` `    ``let ans = maxProfit(prices);` `    `  `    ``// Print the total profit` `    ``console.log(ans);` `    `  `    ``// This code is contributed by garg28harsh.`

Output

`7`

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

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 1: 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;` `}`

## Java

 `import` `java.util.*;`   `class` `GFG {`   `    ``// Function to find the maximum` `    ``// profit in the buy and sell stock` `    ``static` `int` `find(``int``[] prices, ``int` `ind, ``boolean` `buy,` `                    ``int` `c, ``int``[][][] memo)` `    ``{` `        ``// If buy =1 means buy now` `        ``// else sell` `        ``if` `(ind >= prices.length || c >= ``2``) {` `            ``return` `0``;` `        ``}` `        ``if` `(memo[ind][buy ? ``1` `: ``0``] != -``1``) {` `            ``return` `memo[ind][buy ? ``1` `: ``0``];` `        ``}`   `        ``// Already bought, sell now` `        ``if` `(buy) {` `            ``return` `memo[ind][buy ? ``1` `: ``0``] = Math.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 ? ``1` `: ``0``] = Math.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` `    ``static` `int` `maxProfit(``int``[] prices)` `    ``{` `        ``// Here maximum two transaction are allowed`   `        ``// Use 3-D array because here` `        ``// three states are there: i,k,buy/sell` `        ``int``[][][] memo = ``new` `int``[prices.length][``2``][``2``];` `        ``for` `(``int``[][] a : memo) {` `            ``for` `(``int``[] b : a) {` `                ``Arrays.fill(b, -``1``);` `            ``}` `        ``}`   `        ``// Answer` `        ``return` `find(prices, ``0``, ``true``, ``0``, memo);` `    ``}`   `    ``// Driver Code` `    ``public` `static` `void` `main(String[] args)` `    ``{`   `        ``// Given prices` `        ``int``[] prices = { ``3``, ``3``, ``5``, ``0``, ``0``, ``3``, ``1``, ``4` `};`   `        ``// Function Call` `        ``int` `ans = maxProfit(prices);`   `        ``// Answer` `        ``System.out.println(ans);` `    ``}` `}`   `// contributed by akashish__`

## Python3

 `# Python program for the above approach` `from` `typing ``import` `List``, ``Tuple`     `def` `find(prices: ``List``[``int``], ind: ``int``, buy: ``bool``, c: ``int``, memo: ``List``[``List``[``List``[``int``]]]) ``-``> ``int``:` `    ``# If buy =1 means buy now` `    ``# else sell` `    ``if` `ind >``=` `len``(prices) ``or` `c >``=` `2``:` `        ``return` `0` `    ``if` `memo[ind][buy] !``=` `-``1``:` `        ``return` `memo[ind][buy]`   `    ``# Already bought, sell now` `    ``if` `buy:` `        ``memo[ind][buy] ``=` `max``(``-``prices[ind] ``+` `find(prices, ind ``+` `1``, ``not` `buy, c, memo),` `                                ``find(prices, ind ``+` `1``, buy, c, memo))` `        ``return` `memo[ind][buy]` `    ``# Can buy stocks` `    ``else``:` `        ``memo[ind][buy] ``=` `max``(prices[ind] ``+` `find(prices, ind ``+` `1``, ``not` `buy, c``+``1``, memo),` `                                ``find(prices, ind ``+` `1``, buy, c, memo))` `        ``return` `memo[ind][buy]`     `def` `maxProfit(prices: ``List``[``int``]) ``-``> ``int``:` `    ``# Here maximum two transaction are allowed` `    ``memo ``=` `[[[``-``1` `for` `_ ``in` `range``(``2``)] ``for` `_ ``in` `range``(``2``)]` `            ``for` `_ ``in` `range``(``len``(prices))]` `    ``return` `find(prices, ``0``, ``True``, ``0``, memo)`     `# Given prices` `prices ``=` `[``3``, ``3``, ``5``, ``0``, ``0``, ``3``, ``1``, ``4``]`   `# Function Call` `ans ``=` `maxProfit(prices)`   `# Answer` `print``(ans)`   `# This code is contributed by lokeshmvs21.`

## C#

 `using` `System;` `using` `System.Collections.Generic;`   `public` `class` `GFG {` `    ``// Function to find the maximum` `    ``// profit in the buy and sell stock` `    ``static` `int` `find(List<``int``> prices, ``int` `ind, ``bool` `buy,` `                    ``int` `c, ``int``[][][] memo)` `    ``{` `        ``// If buy =1 means buy now` `        ``// else sell` `        ``if` `(ind >= prices.Count || c >= 2)` `            ``return` `0;` `        ``if` `(memo[ind][buy ? 1 : 0] != -1)` `            ``return` `memo[ind][buy ? 1 : 0];`   `        ``// Already bought, sell now` `        ``if` `(buy) {` `            ``return` `memo[ind][buy ? 1 : 0] = Math.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 ? 1 : 0] = Math.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` `    ``static` `int` `maxProfit(List<``int``> prices)` `    ``{` `        ``// Here maximum two transaction are allowed`   `        ``// Use 3-D vector because here` `        ``// three states are there: i,k,buy/sell` `        ``int``[][][] memo = ``new` `int``[prices.Count][][];` `        ``for` `(``int` `i = 0; i < prices.Count; i++) {` `            ``memo[i] = ``new` `int``[];` `            ``for` `(``int` `j = 0; j < 2; j++) {` `                ``memo[i][j] = ``new` `int``;` `                ``for` `(``int` `k = 0; k < 2; k++) {` `                    ``memo[i][j][k] = -1;` `                ``}` `            ``}` `        ``}`   `        ``// Answer` `        ``return` `find(prices, 0, ``true``, 0, memo);` `    ``}`   `    ``static` `public` `void` `Main()` `    ``{` `        ``// Given prices` `        ``List<``int``> prices` `            ``= ``new` `List<``int``>{ 3, 3, 5, 0, 0, 3, 1, 4 };`   `        ``// Function Call` `        ``int` `ans = maxProfit(prices);`   `        ``// Answer` `        ``Console.WriteLine(ans);` `    ``}` `}`   `// This code is contributed by akashish__`

## Javascript

 `// Function to find the maximum` `// profit in the buy and sell stock` `function` `find(prices, ind, buy, c, memo) {` `// If buy =1 means buy now` `// else sell` `if` `(ind >= prices.length || c >= 2) {` `return` `0;` `}` `if` `(memo[ind][buy ? 1 : 0] !== -1) {` `return` `memo[ind][buy ? 1 : 0];` `}`   `// Already bought, sell now` `if` `(buy) {` `memo[ind][buy ? 1 : 0] = Math.max(` `-prices[ind] + find(prices, ind + 1, !buy, c, memo),` `find(prices, ind + 1, buy, c, memo)` `);` `return` `memo[ind][buy ? 1 : 0];` `}` `// Can buy stocks` `else` `{` `memo[ind][buy ? 1 : 0] = Math.max(` `prices[ind] + find(prices, ind + 1, !buy, c + 1, memo),` `find(prices, ind + 1, buy, c, memo)` `);` `return` `memo[ind][buy ? 1 : 0];` `}` `}`   `// Function to find the maximum` `// profit in the buy and sell stock` `function` `maxProfit(prices) {` `// Here maximum two transaction are allowed`   `// Use 3-D array because here` `// three states are there: i,k,buy/sell` `let memo = ``new` `Array(prices.length)` `.fill()` `.map(() => ``new` `Array(2).fill().map(() => ``new` `Array(2).fill(-1)));`   `// Answer` `return` `find(prices, 0, ``true``, 0, memo);` `}`   `// Given prices` `let prices = [3, 3, 5, 0, 0, 3, 1, 4];`   `// Function Call` `let ans = maxProfit(prices);`   `// Answer` `console.log(ans);`

Output

`6`

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

Approach 2: Space Optimized

• We have 4 variables here t1Cost, t2Cost, t1Profit, and t2Profit.
• They represents the minimum cost in each transaction and maximum profit we can have from each transaction t1Cost and t1Profit are very easy to get.
• We have to reinvest the profit we gain from the first transaction. The prices of the second stock minus the max profit we have from first transaction is the minimum cost of second transaction.

## C++14

 `// C++ program for the above approach`   `#include ` `#include ` `using` `namespace` `std;` `// Function to find the maximum` `// profit in the buy and sell stock` `int` `maxProfit(vector<``int``> prices)` `{` `    ``// O(n) time | O(1) space` `    ``if` `(prices.size() <= 1)` `        ``return` `0;`   `    ``int` `t1Cost = INT_MAX, t2Cost = INT_MAX;` `    ``int` `t1Profit = 0, t2Profit = 0;`   `    ``for` `(``int` `price : prices) {` `        ``// first transaction is as same as 121. Best Time to` `        ``// Buy and Sell Stock` `        ``t1Cost = min(t1Cost, price);` `        ``t1Profit = max(t1Profit, price - t1Cost);`   `        ``// reinvest the gained profit in the second` `        ``// transaction` `        ``t2Cost = min(t2Cost, price - t1Profit);` `        ``t2Profit = max(t2Profit, price - t2Cost);` `    ``}` `    ``return` `t2Profit;` `}`   `// 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;` `}`

## Java

 `import` `java.util.ArrayList;` `import` `java.util.List;`   `class` `GFG {`   `    ``// Function to find the maximum` `    ``// profit in the buy and sell stock` `    ``public` `static` `int` `maxProfit(List prices)` `    ``{` `        ``// O(n) time | O(1) space` `        ``if` `(prices.size() <= ``1``)` `            ``return` `0``;`   `        ``int` `t1Cost = Integer.MAX_VALUE, t2Cost` `                                        ``= Integer.MAX_VALUE;` `        ``int` `t1Profit = ``0``, t2Profit = ``0``;`   `        ``for` `(``int` `i = ``0``; i < prices.size(); i++) {` `            ``int` `price = prices.get(i);` `            ``// first transaction is as same as 121. Best` `            ``// Time to Buy and Sell Stock` `            ``t1Cost = Math.min(t1Cost, price);` `            ``t1Profit = Math.max(t1Profit, price - t1Cost);`   `            ``// reinvest the gained profit in the second` `            ``// transaction` `            ``t2Cost = Math.min(t2Cost, price - t1Profit);` `            ``t2Profit = Math.max(t2Profit, price - t2Cost);` `        ``}` `        ``return` `t2Profit;` `    ``}`   `    ``public` `static` `void` `main(String[] args)` `    ``{`   `        ``// Given prices` `        ``List prices = ``new` `ArrayList();` `        ``prices.add(``3``);` `        ``prices.add(``3``);` `        ``prices.add(``5``);` `        ``prices.add(``0``);` `        ``prices.add(``0``);` `        ``prices.add(``3``);` `        ``prices.add(``1``);` `        ``prices.add(``4``);` `        ``// Function Call` `        ``int` `ans = maxProfit(prices);`   `        ``// Answer` `        ``System.out.println(ans);` `    ``}` `}`   `// This code is contributed by akashish__`

## Python3

 `# Python3 program for the above approach`   `# Function to find the maximum` `# profit in the buy and sell stock`     `def` `maxProfit(prices):` `    ``# O(n) time | O(1) space` `    ``if``(``len``(prices) <``=` `1``):` `        ``return` `0`   `    ``t1Cost ``=` `2147483647` `    ``t2Cost ``=` `2147483647` `    ``t1Profit ``=` `0` `    ``t2Profit ``=` `0`   `    ``for` `i ``in` `range``(``0``, ``len``(prices)):` `        ``price ``=` `prices[i]`   `        ``# first transaction is as same as 121.` `        ``# Best Time to Buy and Sell Stock` `        ``t1Cost ``=` `min``(t1Cost, price)` `        ``t1Profit ``=` `max``(t1Profit, price ``-` `t1Cost)`   `        ``# reinvest the gained profit in the second transaction` `        ``t2Cost ``=` `min``(t2Cost, price ``-` `t1Profit)` `        ``t2Profit ``=` `max``(t2Profit, price ``-` `t2Cost)` `    ``return` `t2Profit`     `# Driver Code`   `# Given prices` `prices ``=` `[``3``, ``3``, ``5``, ``0``, ``0``, ``3``, ``1``, ``4``]`   `# Function Call` `ans ``=` `maxProfit(prices)`   `# Answer` `print``(ans)`   `# This code is contributed by akashish__`

## C#

 `using` `System;` `using` `System.Collections.Generic;` `public` `class` `GFG {`   `    ``// Function to find the maximum` `    ``// profit in the buy and sell stock` `    ``public` `static` `int` `maxProfit(List<``int``> prices)` `    ``{` `        ``// O(n) time | O(1) space` `        ``if` `(prices.Count <= 1)` `            ``return` `0;`   `        ``int` `t1Cost = Int32.MaxValue, t2Cost` `                                     ``= Int32.MaxValue;` `        ``int` `t1Profit = 0, t2Profit = 0;`   `        ``for` `(``int` `i = 0; i < prices.Count; i++) {` `            ``int` `price = prices[i];` `            ``// first transaction is as same as 121. Best` `            ``// Time to Buy and Sell Stock` `            ``t1Cost = Math.Min(t1Cost, price);` `            ``t1Profit = Math.Max(t1Profit, price - t1Cost);`   `            ``// reinvest the gained profit in the second` `            ``// transaction` `            ``t2Cost = Math.Min(t2Cost, price - t1Profit);` `            ``t2Profit = Math.Max(t2Profit, price - t2Cost);` `        ``}` `        ``return` `t2Profit;` `    ``}`   `    ``static` `public` `void` `Main()` `    ``{`   `        ``// Given prices` `        ``List<``int``> prices` `            ``= ``new` `List<``int``>{ 3, 3, 5, 0, 0, 3, 1, 4 };` `        ``// Function Call` `        ``int` `ans = maxProfit(prices);`   `        ``// Answer` `        ``Console.WriteLine(ans);` `    ``}` `}`   `// This code is contributed by akashish__`

## Javascript

 `// JS program for the above approach`   `// Function to find the maximum` `// profit in the buy and sell stock` `function` `maxProfit( prices) {` `    ``// O(n) time | O(1) space` `    ``if``(prices.length <= 1)    ``return` `0;` `    `  `    ``let t1Cost = Number.MAX_VALUE, t2Cost = Number.MAX_VALUE;` `    ``let t1Profit = 0, t2Profit = 0;` `    `  `    ``for``(let i=0;i

Output

`6`

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

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;` `}`

## Java

 `// Java code for the above approach`   `import` `java.io.*;` `import` `java.util.*;`   `class` `GFG {`   `    ``// Function to find the maximum` `    ``// profit with atmost K transactions` `    ``static` `int` `find(``int``[] prices, ``int` `ind, ``boolean` `buy,` `                    ``int` `c, ``int` `k, ``int``[][][] memo)` `    ``{`   `        ``// If there are no more transaction` `        ``// allowed, return the profit as 0` `        ``if` `(ind >= prices.length || c >= k)` `            ``return` `0``;`   `        ``// Memoize` `        ``else` `if` `(memo[ind][buy ? ``1` `: ``0``] != -``1``)` `            ``return` `memo[ind][buy ? ``1` `: ``0``];`   `        ``// Already bought, now sell` `        ``if` `(buy) {` `            ``return` `memo[ind][buy ? ``1` `: ``0``]` `                ``= Math.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 ? ``1` `: ``0``]` `                ``= Math.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` `    ``static` `int` `maxProfit(``int` `k, ``int``[] prices)` `    ``{` `        ``// If transactions are greater` `        ``// than number of prices` `        ``if` `(``2` `* k > prices.length) {` `            ``int` `res = ``0``;` `            ``for` `(``int` `i = ``1``; i < prices.length; i++) {` `                ``res += Math.max(``0``,` `                                ``prices[i] - prices[i - ``1``]);` `            ``}` `            ``return` `res;` `        ``}`   `        ``// Maximum k transaction` `        ``int``[][][] memo` `            ``= ``new` `int``[prices.length + ``1``][``2``][k + ``1``];` `        ``for` `(``int``[][] arr2d : memo)` `            ``for` `(``int``[] arr1d : arr2d)` `                ``Arrays.fill(arr1d, -``1``);` `        ``return` `find(prices, ``0``, ``true``, ``0``, k, memo);` `    ``}`   `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``// Given prices` `        ``int``[] prices = { ``2``, ``4``, ``1` `};`   `        ``// Given K` `        ``int` `k = ``2``;`   `        ``// Function Call` `        ``int` `ans = maxProfit(k, prices);`   `        ``// Print answer` `        ``System.out.println(ans);` `    ``}` `}`   `// This code is contributed by lokesh.`

## Python3

 `import` `sys`   `# Function to find the maximum` `# profit with atmost K transactions`     `def` `find(prices, ind, buy, c, k, memo):` `    ``# If there are no more transactions allowed, return the profit as 0` `    ``if` `ind >``=` `len``(prices) ``or` `c >``=` `k:` `        ``return` `0`   `    ``# Memoize` `    ``elif` `memo[ind][buy] !``=` `-``1``:` `        ``return` `memo[ind][buy]`   `    ``# Already bought, now sell` `    ``if` `buy:` `        ``memo[ind][buy] ``=` `max``(` `            ``-``prices[ind] ``+` `find(prices, ind ``+` `1``, ``not` `buy, c, k, memo),` `            ``find(prices, ind ``+` `1``, buy, c, k, memo)` `        ``)` `        ``return` `memo[ind][buy]` `    ``# Stocks can be bought` `    ``else``:` `        ``memo[ind][buy] ``=` `max``(` `            ``prices[ind] ``+` `find(prices, ind ``+` `1``, ``not` `buy, c ``+` `1``, k, memo),` `            ``find(prices, ind ``+` `1``, buy, c, k, memo)` `        ``)` `        ``return` `memo[ind][buy]`     `def` `maxProfit(k, prices):` `    ``# If transactions are greater than number of prices` `    ``if` `2` `*` `k > ``len``(prices):` `        ``res ``=` `0` `        ``for` `i ``in` `range``(``1``, ``len``(prices)):` `            ``res ``+``=` `max``(``0``, prices[i] ``-` `prices[i ``-` `1``])` `        ``return` `res`   `    ``# Maximum k transactions` `    ``memo ``=` `[[[``-``1` `for` `i ``in` `range``(k ``+` `1``)] ``for` `j ``in` `range``(``2``)]` `            ``for` `k ``in` `range``(``len``(prices) ``+` `1``)]` `    ``return` `find(prices, ``0``, ``True``, ``0``, k, memo)`     `# Given prices` `prices ``=` `[``2``, ``4``, ``1``]`   `# Given K` `k ``=` `2`   `# Function Call` `ans ``=` `maxProfit(k, prices)`   `# Print answer` `print``(ans)`

## C#

 `// C# code`   `using` `System;`   `public` `class` `GFG {`   `    ``// Function to find the maximum` `    ``// profit with atmost K transactions` `    ``static` `int` `find(``int``[] prices, ``int` `ind, ``bool` `buy, ``int` `c,` `                    ``int` `k, ``int``[, , ] memo)` `    ``{`   `        ``// If there are no more transaction` `        ``// allowed, return the profit as 0` `        ``if` `(ind >= prices.Length || c >= k)` `            ``return` `0;`   `        ``// Memoize` `        ``else` `if` `(memo[ind, buy ? 1 : 0, c] != -1)` `            ``return` `memo[ind, buy ? 1 : 0, c];`   `        ``// Already bought, now sell` `        ``if` `(buy) {` `            ``return` `memo[ind, buy ? 1 : 0, c]` `                ``= Math.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 ? 1 : 0, c]` `                ``= Math.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` `    ``static` `int` `maxProfit(``int` `k, ``int``[] prices)` `    ``{` `        ``// If transactions are greater` `        ``// than number of prices` `        ``if` `(2 * k > prices.Length) {` `            ``int` `res = 0;` `            ``for` `(``int` `i = 1; i < prices.Length; i++) {` `                ``res += Math.Max(0,` `                                ``prices[i] - prices[i - 1]);` `            ``}` `            ``return` `res;` `        ``}`   `        ``// Maximum k transaction` `        ``int``[, , ] memo` `            ``= ``new` `int``[prices.Length + 1, 2, k + 1];` `        ``for` `(``int` `i = 0; i < memo.GetLength(0); i++)` `            ``for` `(``int` `j = 0; j < memo.GetLength(1); j++)` `                ``for` `(``int` `l = 0; l < memo.GetLength(2); l++)` `                    ``memo[i, j, l] = -1;` `        ``return` `find(prices, 0, ``true``, 0, k, memo);` `    ``}`   `    ``static` `public` `void` `Main()` `    ``{` `        ``// Given prices` `        ``int``[] prices = { 2, 4, 1 };`   `        ``// Given K` `        ``int` `k = 2;`   `        ``// Function Call` `        ``int` `ans = maxProfit(k, prices);`   `        ``// Print answer` `        ``Console.WriteLine(ans);` `    ``}` `}`   `// This code is contributed by akashish__`

## Javascript

 `// Javascript program for the above approach`   `// Function to find the maximum` `// profit with atmost K transactions` `function` `find(prices, ind, buy, c, k, memo) {`   `    ``// If there are no more transaction` `    ``// allowed, return the profit as 0` `    ``if` `(ind >= prices.length || 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] = Math.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] = Math.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` `function` `maxProfit(k, prices) {` `    ``// If transactions are greater` `    ``// than number of prices` `    ``if` `(2 * k > prices.length) {` `        ``let res = 0;` `        ``for` `(let i = 1; i < prices.length; i++) {` `            ``res += Math.max(0, prices[i] - prices[i - 1]);` `        ``}` `        ``return` `res;` `    ``}`   `    ``// Maximum k transaction` `    ``let memo = ``new` `Array(prices.length + 1);` `    ``for` `(let i = 0; i <= prices.length; i++) {` `        ``memo[i] = ``new` `Array(2);` `        ``for` `(let j = 0; j < 2; j++) {` `            ``memo[i][j] = ``new` `Array(k + 1).fill(-1);` `        ``}` `    ``}` `    ``return` `find(prices, 0, 1, 0, k, memo);` `}`   `// Driver Code` `let prices = [2, 4, 1];` `let k = 2;` `let ans = maxProfit(k, prices);` `console.log(ans);`   `// This code is contributed by akashish__`

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)

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 by buying and selling stock with the restriction of after you sell your stock, you cannot buy stock on the next day (i.e., cooldown one day).

Note : Stock must be bought before being sold, and overlapping of transactions is not allowed.

Examples :

Input : arr[] = 1 2 3 0 2
Output : 3
Explanation :
You first buy on day 1 and sell on the day 2 then cooldown, then buy on day 4 and sell on day 5.
Total profit earned is (2-1) + (2-0) = 3, which is the maximum achievable profit.

Input : arr[] = 3 1 6 1 2 4
Output : 7
Explanation :
You first buy at day 2 and sell on the day 3 then cooldown, then again you buy on day 5 and then sell
on day 6. Clearly, total profit earned is (6-1) + (4-2) = 7, which is the maximum achievable profit.

Approach I (Recursion + Memoization) :

The idea is that on any day, either we buy the stock or we don’t depending on the cooldown state. We maintain a boolean variable ‘buy’, which indicates whether we can buy a stock on a particular day. i.e. if we can buy a stock on a day its value will be 1; else, it will be zero. We also maintain a ‘profit’ variable that keeps track of total profit that we have earned so far.
Now the following scenario arises :
If the value of buy variable is 1, then we can either buy stock on that day and reduce our profit by cost of that day and buy = 0, or we can simply move to the next day, and maintaining the buy variable as 1.
If the value of buy variable is 0, it means we need to sell the existing stock first. So, either we sell the stock on the day i and add cost of that day i to the total profit and move to day i+2 (for cooldown) and buy = 1, or we can simply move to day i+1 and buy = 0.

The following approach can be easily implemented using recursion, as shown below :

## C++

 `#include ` `using` `namespace` `std;` `// Function to return the maximum profit that can be` `// made after buying and selling the given stocks` `long` `long` `finder(``int` `i, ``int` `buy, vector<``int``>& v,` `                 ``vector >& dp)` `{` `    ``// No stock left` `    ``if` `(i >= v.size())` `        ``return` `0;` `    ``// Memoization step` `    ``if` `(dp[i][buy] != -1)` `        ``return` `dp[i][buy];` `    ``// Profit variable to keep track of total profit earned` `    ``long` `long` `profit = 0;` `    ``if` `(buy) {` `        ``// either buy the stock or move to the next day` `        ``profit = max(-v[i] + finder(i + 1, 0, v, dp),` `                     ``finder(i + 1, 1, v, dp));` `    ``}` `    ``else` `{` `        ``// either sell the stock or move to next day` `        ``profit = max(v[i] + finder(i + 2, 1, v, dp),` `                     ``finder(i + 1, 0, v, dp));` `    ``}` `    ``// return the profit after storing in the dp vector` `    ``return` `dp[i][buy] = profit;` `}`   `long` `long` `maximumProfit(vector<``int``>& v, ``int` `n)` `{` `    ``vector > dp(n,` `                                  ``vector<``long` `long``>(2, -1));`   `    ``return` `finder(0, 1, v, dp);` `}` `int` `main()` `{`   `    ``vector<``int``> v = { 1, 2, 3, 0, 2 };` `    ``cout << maximumProfit(v, v.size());` `    ``return` `0;` `}`

## Java

 `import` `java.util.Arrays;`   `public` `class` `GFG {` `    ``static` `long` `finder(``int` `i, ``int` `buy, ``int``[] v,` `                       ``long``[][] dp)` `    ``{` `        ``// No stock left` `        ``if` `(i >= v.length) {` `            ``return` `0``;` `        ``}`   `        ``// Memoization step` `        ``if` `(dp[i][buy] != -``1``) {` `            ``return` `dp[i][buy];` `        ``}`   `        ``// Profit variable to keep track of total profit` `        ``// earned` `        ``long` `profit = ``0``;`   `        ``if` `(buy == ``1``) {` `            ``// either buy the stock or move to the next day` `            ``profit` `                ``= Math.max(-v[i] + finder(i + ``1``, ``0``, v, dp),` `                           ``finder(i + ``1``, ``1``, v, dp));` `        ``}` `        ``else` `{` `            ``// either sell the stock or move to next day` `            ``profit` `                ``= Math.max(v[i] + finder(i + ``2``, ``1``, v, dp),` `                           ``finder(i + ``1``, ``0``, v, dp));` `        ``}`   `        ``// return the profit after storing in the dp array` `        ``return` `dp[i][buy] = profit;` `    ``}`   `    ``static` `long` `maximumProfit(``int``[] v)` `    ``{` `        ``int` `n = v.length;` `        ``long``[][] dp = ``new` `long``[n][``2``];` `        ``for` `(``long``[] row : dp) {` `            ``Arrays.fill(row, -``1``);` `        ``}` `        ``return` `finder(``0``, ``1``, v, dp);` `    ``}`   `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``int``[] v = { ``1``, ``2``, ``3``, ``0``, ``2` `};` `        ``System.out.println(maximumProfit(v));` `    ``}` `}`

## Python3

 `def` `finder(i, buy, v, dp):` `    ``# No stock left` `    ``if` `i >``=` `len``(v):` `        ``return` `0`   `    ``# Memoization step` `    ``if` `dp[i][buy] !``=` `-``1``:` `        ``return` `dp[i][buy]`   `    ``# Profit variable to keep track of total profit earned` `    ``profit ``=` `0`   `    ``if` `buy ``=``=` `1``:` `        ``# Either buy the stock or move to the next day` `        ``profit ``=` `max``(``-``v[i] ``+` `finder(i ``+` `1``, ``0``, v, dp), finder(i ``+` `1``, ``1``, v, dp))` `    ``else``:` `        ``# Either sell the stock or move to the next day` `        ``profit ``=` `max``(v[i] ``+` `finder(i ``+` `2``, ``1``, v, dp), finder(i ``+` `1``, ``0``, v, dp))`   `    ``# Return the profit after storing it in the dp list` `    ``dp[i][buy] ``=` `profit` `    ``return` `profit`     `def` `maximum_profit(v):` `    ``# Create a dp list with initial values of -1` `    ``n ``=` `len``(v)` `    ``dp ``=` `[[``-``1``, ``-``1``] ``for` `_ ``in` `range``(n)]` `    ``return` `finder(``0``, ``1``, v, dp)`     `v ``=` `[``1``, ``2``, ``3``, ``0``, ``2``]` `print``(maximum_profit(v))`

## C#

 `using` `System;` `using` `System.Collections.Generic;`   `public` `class` `GFG {` `    ``static` `long` `Finder(``int` `i, ``int` `buy, List<``int``> v,` `                       ``List > dp)` `    ``{` `        ``// No stock left` `        ``if` `(i >= v.Count)` `            ``return` `0;`   `        ``// Memoization step` `        ``if` `(dp[i][buy] != -1)` `            ``return` `dp[i][buy];`   `        ``// Profit variable to keep track of total profit` `        ``// earned` `        ``long` `profit = 0;`   `        ``if` `(buy == 1) {` `            ``// Either buy the stock or move to the next day` `            ``profit` `                ``= Math.Max(-v[i] + Finder(i + 1, 0, v, dp),` `                           ``Finder(i + 1, 1, v, dp));` `        ``}` `        ``else` `{` `            ``// Either sell the stock or move to the next day` `            ``profit` `                ``= Math.Max(v[i] + Finder(i + 2, 1, v, dp),` `                           ``Finder(i + 1, 0, v, dp));` `        ``}`   `        ``// Return the profit after storing it in the dp list` `        ``dp[i][buy] = profit;` `        ``return` `profit;` `    ``}`   `    ``static` `long` `MaximumProfit(List<``int``> v, ``int` `n)` `    ``{` `        ``// Create a dp list with initial values of -1` `        ``List > dp = ``new` `List >();`   `        ``for` `(``int` `i = 0; i < n; i++) {` `            ``dp.Add(``new` `List<``long``>{ -1, -1 });` `        ``}`   `        ``return` `Finder(0, 1, v, dp);` `    ``}`   `    ``static` `void` `Main(``string``[] args)` `    ``{` `        ``List<``int``> v = ``new` `List<``int``>{ 1, 2, 3, 0, 2 };` `        ``Console.WriteLine(MaximumProfit(v, v.Count));` `    ``}` `}`

## Javascript

 `function` `finder(i, buy, v, dp) {` `    ``// No stock left` `    ``if` `(i >= v.length)` `        ``return` `0;` `    `  `    ``// Memoization step` `    ``if` `(dp[i][buy] !== -1)` `        ``return` `dp[i][buy];` `    `  `    ``// Profit variable to keep track of total profit earned` `    ``let profit = 0;` `    `  `    ``if` `(buy === 1) {` `        ``// Either buy the stock or move to the next day` `        ``profit = Math.max(-v[i] + finder(i + 1, 0, v, dp), finder(i + 1, 1, v, dp));` `    ``} ``else` `{` `        ``// Either sell the stock or move to the next day` `        ``profit = Math.max(v[i] + finder(i + 2, 1, v, dp), finder(i + 1, 0, v, dp));` `    ``}` `    `  `    ``// Return the profit after storing it in the dp array` `    ``dp[i][buy] = profit;` `    ``return` `profit;` `}`   `function` `maximumProfit(v) {` `    ``// Create a dp array with initial values of -1` `    ``const n = v.length;` `    ``const dp = Array.from(Array(n), () => Array(2).fill(-1));` `    ``return` `finder(0, 1, v, dp);` `}`   `const v = [1, 2, 3, 0, 2];` `console.log(maximumProfit(v));`

Output

`3`

Time Complexity : O(N), Where N is the length of the given array.
Auxiliary Space : O(N^2)

Approach II (Dynamic Programming) :

We need to maintain three states for each day. The first state will be max profit we can make if we have one stock yet to be sold. The second state will be the max profit we can make if we have no stock left to be sold. The third state is the cooldown state. It is similar to second state, but we have completed the cooldown of 1 day after selling the stock. Each state can be maintained using DP vector.

The following approach is implemented below :

## C++

 `#include ` `using` `namespace` `std;`   `long` `long` `maximumProfit(vector<``int``>& v, ``int` `n)` `{` `    ``vector > dp(v.size() + 1,` `                                  ``vector<``long` `long``>(3));` `    ``dp = -v;` `    ``for` `(``int` `i = 1; i <= n; i++) ` `    ``{` `        ``// Maximum of buy state profit till previous day or` `        ``// buying a new stock with cooldown state of previous day` `        ``dp[i] = max(dp[i - 1], dp[i - 1] - v[i]);` `        ``// Maximum of sold state profit till previous day or` `        ``// selling the stock on current day with buy state of previous day` `        ``dp[i] = max(dp[i - 1], dp[i - 1] + v[i]);` `          ``// Sold state of previous day` `        ``dp[i] = dp[i - 1];` `    ``}` `      ``// return Sold state profit of final day` `    ``return` `dp[n - 1];           ` `}`   `int` `main()` `{` `    ``vector<``int``> v = { 1, 2, 3, 0, 2 };` `    ``cout << maximumProfit(v, v.size());` `    ``return` `0;` `}`

## Java

 `import` `java.util.Arrays;`   `public` `class` `GFG {` `    ``public` `static` `long` `maximumProfit(``int``[] v, ``int` `n) {` `        ``long``[][] dp = ``new` `long``[n][``3``];` `        ``dp[``0``][``0``] = -v[``0``];` `        ``for` `(``int` `i = ``1``; i < n; i++) {` `            ``// Maximum of buy state profit till previous day or` `            ``// buying a new stock with cooldown state of previous day` `            ``dp[i][``0``] = Math.max(dp[i - ``1``][``0``], dp[i - ``1``][``2``] - v[i]);` `            ``// Maximum of sold state profit till previous day or` `            ``// selling the stock on current day with buy state of previous day` `            ``dp[i][``1``] = Math.max(dp[i - ``1``][``1``], dp[i - ``1``][``0``] + v[i]);` `            ``// Sold state of previous day` `            ``dp[i][``2``] = dp[i - ``1``][``1``];` `        ``}` `        ``// return Sold state profit of final day` `        ``return` `dp[n - ``1``][``1``];` `    ``}`   `    ``public` `static` `void` `main(String[] args) {` `        ``int``[] v = {``1``, ``2``, ``3``, ``0``, ``2``};` `        ``System.out.println(maximumProfit(v, v.length));` `    ``}` `}`

## Python3

 `def` `maximumProfit(v):` `    ``n ``=` `len``(v)` `    ``dp ``=` `[[``0``, ``0``, ``0``] ``for` `_ ``in` `range``(n ``+` `1``)]` `    ``dp[``0``][``0``] ``=` `-``v[``0``]`   `    ``for` `i ``in` `range``(``1``, n ``+` `1``):` `        ``# Maximum of buy state profit till the previous day or` `        ``# buying a new stock with the cooldown state of the previous day` `        ``dp[i][``0``] ``=` `max``(dp[i ``-` `1``][``0``], dp[i ``-` `1``][``2``] ``-` `v[i ``-` `1``])`   `        ``# Maximum of sold state profit till the previous day or` `        ``# selling the stock on the current day with the buy state of the previous day` `        ``dp[i][``1``] ``=` `max``(dp[i ``-` `1``][``1``], dp[i ``-` `1``][``0``] ``+` `v[i ``-` `1``])`   `        ``# Sold state of the previous day` `        ``dp[i][``2``] ``=` `dp[i ``-` `1``][``1``]`   `    ``# Return the sold state profit of the final day` `    ``return` `dp[n][``1``]`     `v ``=` `[``1``, ``2``, ``3``, ``0``, ``2``]` `print``(maximumProfit(v))`

## C#

 `using` `System;` `using` `System.Collections.Generic;`   `public` `class` `GFG {` `    ``static` `long` `MaximumProfit(List<``int``> v, ``int` `n)` `    ``{` `        ``List > dp = ``new` `List >();`   `        ``// Initialize the dp list with initial values of 0` `        ``for` `(``int` `i = 0; i <= n; i++) {` `            ``dp.Add(``new` `List<``long``>{ 0, 0, 0 });` `        ``}`   `        ``dp = -v;`   `        ``for` `(``int` `i = 1; i <= n; i++) {` `            ``// Maximum of buy state profit till the previous` `            ``// day or buying a new stock with the cooldown` `            ``// state of the previous day` `            ``dp[i] = Math.Max(dp[i - 1],` `                                ``dp[i - 1] - v[i - 1]);`   `            ``// Maximum of sold state profit till the` `            ``// previous day or selling the stock on the` `            ``// current day with the buy state of the` `            ``// previous day` `            ``dp[i] = Math.Max(dp[i - 1],` `                                ``dp[i - 1] + v[i - 1]);`   `            ``// Sold state of the previous day` `            ``dp[i] = dp[i - 1];` `        ``}`   `        ``// Return the sold state profit of the final day` `        ``return` `dp[n];` `    ``}`   `    ``static` `void` `Main(``string``[] args)` `    ``{` `        ``List<``int``> v = ``new` `List<``int``>{ 1, 2, 3, 0, 2 };` `        ``Console.WriteLine(MaximumProfit(v, v.Count));` `    ``}` `}`

## Javascript

 `function` `maximumProfit(v) {` `    ``const n = v.length;` `    ``const dp = Array.from({ length: n + 1 }, () => [0, 0, 0]);` `    ``dp = -v;`   `    ``for` `(let i = 1; i <= n; i++) {` `        ``// Maximum of buy state profit till the previous day or` `        ``// buying a new stock with the cooldown state of the previous day` `        ``dp[i] = Math.max(dp[i - 1], dp[i - 1] - v[i - 1]);`   `        ``// Maximum of sold state profit till the previous day or` `        ``// selling the stock on the current day with the buy state of the previous day` `        ``dp[i] = Math.max(dp[i - 1], dp[i - 1] + v[i - 1]);`   `        ``// Sold state of the previous day` `        ``dp[i] = dp[i - 1];` `    ``}`   `    ``// Return the sold state profit of the final day` `    ``return` `dp[n];` `}`   `const v = [1, 2, 3, 0, 2];` `console.log(maximumProfit(v));`

Output

`3`

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

My Personal Notes arrow_drop_up