Given an array prices[] representing stock prices, find the maximum total profit that can be earned by buying and selling the stock any number of times.
Note: We can only sell a stock which we have bought earlier and we cannot hold multiple stocks on any day.
Examples:
Input: prices[] = [100, 180, 260, 310, 40, 535, 695] Output: 865 Explanation: Buy the stock on day 0 and sell it on day 3 = 310 - 100 = 210 and Buy the stock on day 4 and sell it on day 6 = 695 - 40 = 655 so the Maximum Profit is = 210 + 655 = 865.
Input: prices[] = [4, 2] Output: 0 Explanation: Stock prices keep decreasing, there is no chance to sell at a higher price after buying, so no profit can be made.
[Naive Approach] By Trying All Possibility - O(2n) Time and O(n) Space
The idea is to use recursion to simulate all choices of buying and selling. For each day, you can either skip it or buy on that day. If you buy at day i, then you try all possible selling days j > i where price[j] > price[i].
C++
#include<iostream>#include<vector>usingnamespacestd;// Recursive function to find max profitintmaxProfitRec(vector<int>&price,intstart,intend){intres=0;// Try every possible pair of buy (i) and sell (j)for(inti=start;i<end;i++){for(intj=i+1;j<=end;j++){// Valid transaction if selling price > buying priceif(price[j]>price[i]){// Current profit + profit from left and right partsintcurr=(price[j]-price[i])+maxProfitRec(price,start,i-1)+maxProfitRec(price,j+1,end);res=max(res,curr);}}}returnres;}intmaxProfit(vector<int>&prices){returnmaxProfitRec(prices,0,prices.size()-1);}intmain(){vector<int>prices={100,180,260,310,40,535,695};cout<<maxProfit(prices);return0;}
Java
publicclassGFG{// Recursive function to find max profitstaticintmaxProfitRec(int[]price,intstart,intend){intres=0;// Try every possible pair of buy (i) and sell (j)for(inti=start;i<end;i++){for(intj=i+1;j<=end;j++){// Valid transaction if selling price > buying priceif(price[j]>price[i]){// Current profit + profit from left and right partsintcurr=(price[j]-price[i])+maxProfitRec(price,start,i-1)+maxProfitRec(price,j+1,end);res=Math.max(res,curr);}}}returnres;}staticintmaxProfit(int[]prices){returnmaxProfitRec(prices,0,prices.length-1);}publicstaticvoidmain(String[]args){int[]prices={100,180,260,310,40,535,695};System.out.println(maxProfit(prices));}}
Python
defmaxProfitRec(price,start,end):res=0# Try every possible pair of buy (i) and sell (j)foriinrange(start,end):forjinrange(i+1,end+1):# Valid transaction if selling price > buying priceifprice[j]>price[i]:curr=(price[j]-price[i])+ \
maxProfitRec(price,start,i-1)+ \
maxProfitRec(price,j+1,end)res=max(res,curr)returnresdefmaxProfit(prices):returnmaxProfitRec(prices,0,len(prices)-1)if__name__=="__main__":prices=[100,180,260,310,40,535,695]print(maxProfit(prices))
C#
usingSystem;classGFG{// Recursive function to find max profitstaticintmaxProfitRec(int[]price,intstart,intend){intres=0;// Try every possible pair of buy (i) and sell (j)for(inti=start;i<end;i++){for(intj=i+1;j<=end;j++){// Valid transaction if selling price > buying priceif(price[j]>price[i]){intcurr=(price[j]-price[i])+maxProfitRec(price,start,i-1)+maxProfitRec(price,j+1,end);res=Math.Max(res,curr);}}}returnres;}staticintmaxProfit(int[]prices){returnmaxProfitRec(prices,0,prices.Length-1);}staticvoidMain(){int[]prices={100,180,260,310,40,535,695};Console.WriteLine(maxProfit(prices));}}
JavaScript
functionmaxProfitRec(price,start,end){letres=0;// Try every possible pair of buy (i) and sell (j)for(leti=start;i<end;i++){for(letj=i+1;j<=end;j++){// Valid transaction if selling price > buying priceif(price[j]>price[i]){letcurr=(price[j]-price[i])+maxProfitRec(price,start,i-1)+maxProfitRec(price,j+1,end);res=Math.max(res,curr);}}}returnres;}functionmaxProfit(prices){returnmaxProfitRec(prices,0,prices.length-1);}// Driver Codeletprices=[100,180,260,310,40,535,695];console.log(maxProfit(prices));
Output
865
[Better Approach] Using Local Minima and Maxima - O(n) Time and O(1) Space
The idea is to traverse the array from left to right and Find local minima (where price starts rising) and then a local maxima (where price stops rising). Compute the difference between two and add to the result.
Below is the implementation of the algorithm
C++
#include<iostream>#include<vector>usingnamespacestd;intmaxProfit(vector<int>&prices){intn=prices.size();// Local MinimaintlMin=prices[0];// Local MaximaintlMax=prices[0];intres=0;inti=0;while(i<n-1){// Find local minima while(i<n-1&&prices[i]>=prices[i+1]){i++;}lMin=prices[i];// Local Maximawhile(i<n-1&&prices[i]<=prices[i+1]){i++;}lMax=prices[i];// Add current profit res=res+(lMax-lMin);}returnres;}intmain(){vector<int>prices={100,180,260,310,40,535,695};cout<<maxProfit(prices);return0;}
C
#include<stdio.h>intmaxProfit(intprices[],intn){intlMin=prices[0];intlMax=prices[0];intres=0;inti=0;while(i<n-1){// Find local minimawhile(i<n-1&&prices[i]>=prices[i+1]){i++;}lMin=prices[i];// Local Maximawhile(i<n-1&&prices[i]<=prices[i+1]){i++;}lMax=prices[i];// Add current profitres+=(lMax-lMin);}returnres;}// Driver Codeintmain(){intprices[]={100,180,260,310,40,535,695};intn=sizeof(prices)/sizeof(prices[0]);printf("%d\n",maxProfit(prices,n));return0;}
Java
classGfG{staticintmaxProfit(int[]prices){intn=prices.length;intlMin=prices[0];intlMax=prices[0];intres=0;inti=0;while(i<n-1){// Find local minimawhile(i<n-1&&prices[i]>=prices[i+1]){i++;}lMin=prices[i];// Local Maximawhile(i<n-1&&prices[i]<=prices[i+1]){i++;}lMax=prices[i];// Add current profitres+=(lMax-lMin);}returnres;}publicstaticvoidmain(String[]args){int[]prices={100,180,260,310,40,535,695};System.out.println(maxProfit(prices));}}
Python
defmaxProfit(prices):n=len(prices)lMin=prices[0]lMax=prices[0]res=0i=0whilei<n-1:# Find local minimawhilei<n-1andprices[i]>=prices[i+1]:i+=1lMin=prices[i]# Local Maximawhilei<n-1andprices[i]<=prices[i+1]:i+=1lMax=prices[i]# Add current profitres+=(lMax-lMin)returnresif__name__=="__main__":prices=[100,180,260,310,40,535,695]print(maxProfit(prices))
C#
usingSystem;classGfG{staticintmaxProfit(int[]prices){intn=prices.Length;intlMin=prices[0];intlMax=prices[0];intres=0;inti=0;while(i<n-1){// Find local minimawhile(i<n-1&&prices[i]>=prices[i+1]){i++;}lMin=prices[i];// Local Maximawhile(i<n-1&&prices[i]<=prices[i+1]){i++;}lMax=prices[i];// Add current profitres+=(lMax-lMin);}returnres;}staticvoidMain(){int[]prices={100,180,260,310,40,535,695};Console.WriteLine(maxProfit(prices));}}
JavaScript
functionmaxProfit(prices){letn=prices.length;letlMin=prices[0];letlMax=prices[0];letres=0;leti=0;while(i<n-1){// Find local minimawhile(i<n-1&&prices[i]>=prices[i+1]){i++;}lMin=prices[i];// Local Maximawhile(i<n-1&&prices[i]<=prices[i+1]){i++;}lMax=prices[i];// Add current profitres+=(lMax-lMin);}returnres;}// Driver Code constprices=[100,180,260,310,40,535,695];console.log(maxProfit(prices));
Output
865
[Expected Approach] By Accumulating Profit - O(n) Time and O(1) Space
The idea is that profit only comes when prices rise. If the price goes up from one day to the next, we can think of it as buying yesterday and selling today. Instead of waiting for the exact bottom and top, we simply grab every small upward move. Adding these small gains together is the same as if we had bought at each valley and sold at each peak because every rise between them gets counted.
Below is the implementation of the algorithm:
C++
#include<iostream>#include<vector>usingnamespacestd;intmaxProfit(constvector<int>&prices){intres=0;// Keep on adding the difference between// adjacent when the prices afor(inti=1;i<prices.size();i++){if(prices[i]>prices[i-1])res+=prices[i]-prices[i-1];}returnres;}intmain(){vector<int>prices={100,180,260,310,40,535,695};cout<<maxProfit(prices)<<endl;return0;}
C
#include<stdio.h>intmaxProfit(constint*prices,intn){intres=0;// Keep on adding the difference between// adjacent when the prices afor(inti=1;i<n;i++){if(prices[i]>prices[i-1])res+=prices[i]-prices[i-1];}returnres;}intmain(){intprices[]={100,180,260,310,40,535,695};intsize=sizeof(prices)/sizeof(prices[0]);printf("%d\n",maxProfit(prices,size));return0;}
Java
importjava.util.Arrays;classGfG{staticintmaxProfit(int[]prices){intres=0;// Keep on adding the difference between// adjacent when the prices afor(inti=1;i<prices.length;i++){if(prices[i]>prices[i-1])res+=prices[i]-prices[i-1];}returnres;}publicstaticvoidmain(String[]args){int[]prices={100,180,260,310,40,535,695};System.out.println(maxProfit(prices));}}
Python
defmaxProfit(prices):res=0# Keep on adding the difference between# adjacent when the prices aforiinrange(1,len(prices)):ifprices[i]>prices[i-1]:res+=prices[i]-prices[i-1]returnresif__name__=="__main__":prices=[100,180,260,310,40,535,695]print(maxProfit(prices))
C#
usingSystem;usingSystem.Collections.Generic;classGfG{staticintmaxProfit(List<int>prices){intres=0;// Keep on adding the difference between// adjacent when the prices afor(inti=1;i<prices.Count;i++){if(prices[i]>prices[i-1])res+=prices[i]-prices[i-1];}returnres;}staticvoidMain(string[]args){List<int>prices=newList<int>{100,180,260,310,40,535,695};Console.WriteLine(maxProfit(prices));}}
JavaScript
functionmaxProfit(prices){letres=0;// Keep on adding the difference between// adjacent when the prices afor(leti=1;i<prices.length;i++){if(prices[i]>prices[i-1])res+=prices[i]-prices[i-1];}returnres;}// Driver Code constprices=[100,180,260,310,40,535,695];console.log(maxProfit(prices));