Best Time to Buy and Sell Stock

17 Jun, 2022
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: 5Explanation: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: 0Explanation: 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 maximize the profit we have to minimize 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 minimum 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 maximize the max_profit.
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 maximize the max_profit.
Finally return the max_profit.
Below is the implementation of the above approach:
C++
Java
Python3
// C++ code for the above approach#include <iostream>using namespace std; 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 Codeint main(){    int prices[] = { 7, 1, 5, 6, 4 };    int n = sizeof(prices) / sizeof(prices[0]);    int max_profit = maxProfit(prices, n);    cout << max_profit << endl;    return 0;}
// Java code for the above approachclass 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
## 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 codeif __name__=='__main__':     prices = [ 7, 1, 5, 6, 4 ];    n = len(prices)    max_profit = maxProfit(prices, n);    print(max_profit)
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++
Java
Python3
C#
Javascript
// C++ program for the above approach #include <bits/stdc++.h>#include <iostream>using namespace std; // Function to find maximum profit possible// by buying and selling at most one stackint findMaximumProfit(vector<int>& prices, int i, int k,                      bool buy, vector<vector<int> >& 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 stockint maxProfit(vector<int>& prices){     int n = prices.size();    vector<vector<int> > v(n, vector<int>(2, -1));     // buy = 1 because atmost one    // transaction is allowed    return findMaximumProfit(prices, 0, 1, 1, v);} // Driver Codeint 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 code for the above approachimport 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
# Python 3 program for the above approach  # Function to find maximum profit possible# by buying and selling at most one stackdef 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 stockdef 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 Codeif __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# program for above approachusing 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.
<script>// Javascript code for the above approach  // Function to find maximum profit possible// by buying and selling at most one stackfunction findMaximumProfit(prices, i, k, buy, 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    let 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, 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 stockfunction maxProfit(prices) {    let n = prices.length;    let v = new Array(n).fill(0).map(() => new Array(2).fill(-1))     // buy = 1 because atmost one    // transaction is allowed    return findMaximumProfit(prices, 0, 1, 1, v);} // Driver Code // Given priceslet prices = [7, 1, 5, 3, 6, 4]; // Function Call to find the// maximum profit possible by// buying and selling a single stocklet ans = maxProfit(prices); // Print answerdocument.write(ans);  // This code is contributed by Saurabh Jaiswal</script>
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: 7Explanation: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: 4Explanation: 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 <bits/stdc++.h>using namespace std; // Function to calculate maximum// profit possible by buying or// selling stocks any number of timesint find(int ind, vector<int>& v, bool buy,         vector<vector<int> >& 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 timesint maxProfit(vector<int>& prices){    int n = prices.size();    if (n < 2)        return 0;     vector<vector<int> > v(n + 1, vector<int>(2, -1));    return find(0, prices, 1, v);} // Driver Codeint 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;}
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: 6 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: 4 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 <bits/stdc++.h>#include <iostream>using namespace std; // Function to find the maximum// profit in the buy and sell stockint find(vector<int>& prices, int ind, bool buy, int c,         vector<vector<vector<int> > >& 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 stockint 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<vector<vector<int> > > memo(        prices.size(),        vector<vector<int> >(2, vector<int>(2, -1)));     // Answer    return find(prices, 0, 1, 0, memo);} // Driver Codeint 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;}
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: 2Explanation: 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: 7Explanation: 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 <bits/stdc++.h>#include <iostream>using namespace std; // Function to find the maximum// profit with atmost K transactionsint find(vector<int>& prices, int ind, bool buy, int c,         int k, vector<vector<vector<int> > >& 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 stockint 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<vector<vector<int> > > memo(        prices.size() + 1,        vector<vector<int> >(2, vector<int>(k + 1, -1)));    return find(prices, 0, 1, 0, k, memo);} // Driver Codeint 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;}
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)
 
lokeshpotta20
samim2000
_saurabh_jaiswal
ukasp
simmytarika5
nehajmi08
piyushmulatkar11
202051178
subhamgoyal2014
jainlovely450
Dynamic Programming
Dynamic Programming
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Find if there is a path between two vertices in an undirected graph
Count number of binary strings without consecutive 1's
Find if a string is interleaved of two other strings | DP-33
Optimal Substructure Property in Dynamic Programming | DP-2
Maximum sum such that no two elements are adjacent
Unique paths in a Grid with Obstacles
How to solve a Dynamic Programming Problem ?
Maximum profit by buying and selling a share at most twice
Word Break Problem | DP-32
Top 50 Dynamic Programming Coding Problems for Interviews