Maximize profit in buying and selling stocks with Rest condition
Last Updated :
04 Dec, 2023
The price of a stock on each day is given in an array arr[] for N days, the task is to find the maximum profit that can be made by buying and selling the stocks in those days with conditions that the stock must be sold before buying again and stock cannot be bought on the next day of selling a stock. (i.e, rest for at least one day).
Examples:Â
Input: arr[] = {2, 4, 5, 0, 2}Â
Output: 4Â
Explanation: Buy at cost 2 and sell at cost 4, profit = 2. Buy at cost 0 and sell at cost 2, profit = 2. Total profit = 4.
Input: arr[] = {2, 0, 5, 1, 8}Â
Output: 8Â
Â
Approach :Â
Consider three states: REST, HOLD, and SOLD.
REST means not doing anything.Â
HOLD means holding stock (bought a stock and have not sold).Â
SOLD means state after selling the stock.
To reach the REST state, do nothing.Â
To reach the HOLD state, buy the stock.Â
To reach the SOLD state, sell the stock for which first there is a need to buy.
By the above actions, a transition diagram is made.Â
By using this transition diagram the profit can be found out.
On ith day:Â
Â
- rest[i] denotes maximum profit made by resting on day i. Since ith day is rest day, the stock might have been sold on (i-1)th day or might not have been sold. The value of rest[i] = max( rest[i-1], sold[i-1]).
- hold[i] denotes maximum profit made by buying on ith day or by buying on some day before ith and resting on ith day. So, the value of hold[i] = max( hold[i-1], rest[i-1]+price[i]).
- sold[i] denotes maximum profit by selling ith day. Stock must have been bought on some day before selling it on the ith day. Hence sold[i] = hold[i-1] + price[i].Â
Â
Hence, the final answer will be the Â
maximum of sold[n-1] and rest[n-1].
Below is the implementation of the above approach:Â
C++
#include <bits/stdc++.h>
using namespace std;
int maxProfit( int prices[], int n)
{
if (n <= 1)
return 0;
int rest[n] = { 0 };
int hold[n] = { 0 };
int sold[n] = { 0 };
rest[0] = 0;
hold[0] = -prices[0];
sold[0] = 0;
for ( int i = 1; i < n; i++) {
rest[i] = max(rest[i - 1],
sold[i - 1]);
hold[i] = max(hold[i - 1],
rest[i - 1]
- prices[i]);
sold[i] = hold[i - 1] + prices[i];
}
return max(rest[n - 1],
sold[n - 1]);
}
int main()
{
int price[] = { 2, 4,
5, 0, 2 };
int n = sizeof (price)
/ sizeof (price[0]);
cout << maxProfit(price, n)
<< endl;
return 0;
}
|
Java
import java.io.*;
public class GFG{
static int maxProfit( int prices[], int n)
{
if (n <= 1 )
return 0 ;
int rest[] = new int [n];
int hold[] = new int [ 9 ];
int sold[] = new int [ 9 ];
rest[ 0 ] = 0 ;
hold[ 0 ] = -prices[ 0 ];
sold[ 0 ] = 0 ;
for ( int i = 1 ; i < n; i++)
{
rest[i] = Math.max(rest[i - 1 ],
sold[i - 1 ]);
hold[i] = Math.max(hold[i - 1 ],
rest[i - 1 ] -
prices[i]);
sold[i] = hold[i - 1 ] + prices[i];
}
return Math.max(rest[n - 1 ],
sold[n - 1 ]);
}
public static void main(String[] args)
{
int price[] = { 2 , 4 , 5 , 0 , 2 };
int n = price.length;
System.out.print(maxProfit(price, n) + "\n" );
}
}
|
Python3
def maxProfit(prices, n):
if (n < = 1 ):
return 0
rest = [ 0 ] * n
hold = [ 0 ] * n
sold = [ 0 ] * n
rest[ 0 ] = 0
hold[ 0 ] = - prices[ 0 ]
sold[ 0 ] = 0
for i in range ( 1 , n):
rest[i] = max (rest[i - 1 ],
sold[i - 1 ])
hold[i] = max (hold[i - 1 ],
rest[i - 1 ] -
prices[i])
sold[i] = hold[i - 1 ] + prices[i]
return max (rest[n - 1 ],
sold[n - 1 ])
price = [ 2 , 4 , 5 , 0 , 2 ]
n = len (price)
print (maxProfit(price, n))
|
C#
using System;
class GFG{
static int maxProfit( int [] prices, int n)
{
if (n <= 1)
return 0;
int [] rest = new int [n];
int [] hold = new int [9];
int [] sold = new int [9];
rest[0] = 0;
hold[0] = -prices[0];
sold[0] = 0;
for ( int i = 1; i < n; i++)
{
rest[i] = Math.Max(rest[i - 1],
sold[i - 1]);
hold[i] = Math.Max(hold[i - 1],
rest[i - 1] -
prices[i]);
sold[i] = hold[i - 1] + prices[i];
}
return Math.Max(rest[n - 1],
sold[n - 1]);
}
static void Main()
{
int [] price = { 2, 4, 5, 0, 2 };
int n = price.Length;
Console.WriteLine(maxProfit(price, n));
}
}
|
Javascript
<script>
function maxProfit( prices, n)
{
if (n <= 1)
return 0;
let rest = [];
for (let k = 0;k<n;k++)
rest.push(0);
let hold = [];
for (let k = 0;k<n;k++)
hold.push(0);
let sold = [];
for (let k = 0;k<n;k++)
sold.push(0);
rest[0] = 0;
hold[0] = -prices[0];
sold[0] = 0;
for (let i = 1; i < n; i++) {
rest[i] = Math.max(rest[i - 1],
sold[i - 1]);
hold[i] = Math.max(hold[i - 1],
rest[i - 1]
- prices[i]);
sold[i] = hold[i - 1] + prices[i];
}
return Math.max(rest[n - 1],
sold[n - 1]);
}
let price = [ 2, 4,
5, 0, 2 ];
let n = price.length;
document.write( maxProfit(price, n),'<br>');
</script>
|
Time Complexity: O(N)Â
Auxiliary Space: O(N)
Recursive Approach:
Everyday, We have two choices : Buy/Sell this stock OR ignore and move to the next one.
Along with day, we also need to maintain a buy variable which will tell us that if we wantÂ
to do a transaction today it will be of which type (Buy or Sell) and According to that we willÂ
make recursive calls and calculate the answer
C++
#include <bits/stdc++.h>
using namespace std;
int f( int idx, int buy, int prices[], int n)
{
if (idx >= n) {
return 0;
}
int profit = 0;
if (buy == 0) {
profit
= max(-prices[idx] + f(idx + 1, 1, prices, n),
f(idx + 1, 0, prices, n));
}
else {
profit = max(prices[idx] + f(idx + 2, 0, prices, n),
f(idx + 1, 1, prices, n));
}
return profit;
}
int maxProfit( int prices[], int n)
{
return f(0, 0, prices, n);
}
int main()
{
int price[] = { 2, 4, 5, 0, 2 };
int n = sizeof (price) / sizeof (price[0]);
cout << maxProfit(price, n) << endl;
return 0;
}
|
Java
public class Main {
public static int f( int idx, int buy, int [] prices, int n) {
if (idx >= n) {
return 0 ;
}
int profit = 0 ;
if (buy == 0 ) {
profit = Math.max(-prices[idx] + f(idx + 1 , 1 , prices, n),
f(idx + 1 , 0 , prices, n));
}
else {
profit = Math.max(prices[idx] + f(idx + 2 , 0 , prices, n),
f(idx + 1 , 1 , prices, n));
}
return profit;
}
public static int maxProfit( int [] prices, int n) {
return f( 0 , 0 , prices, n);
}
public static void main(String[] args) {
int [] price = { 2 , 4 , 5 , 0 , 2 };
int n = price.length;
System.out.println(maxProfit(price, n));
}
}
|
Python3
def f(idx, buy, prices, n):
if idx > = n:
return 0
profit = 0
if buy = = 0 :
profit = max ( - prices[idx] + f(idx + 1 , 1 , prices, n), f(idx + 1 , 0 , prices, n))
else :
profit = max (prices[idx] + f(idx + 2 , 0 , prices, n), f(idx + 1 , 1 , prices, n))
return profit
def maxProfit(prices, n):
return f( 0 , 0 , prices, n)
price = [ 2 , 4 , 5 , 0 , 2 ]
n = len (price)
print (maxProfit(price, n))
|
C#
using System;
public class MainClass {
public static int f( int idx, int buy, int [] prices, int n) {
if (idx >= n) {
return 0;
}
int profit = 0;
if (buy == 0) {
profit = Math.Max(-prices[idx] + f(idx + 1, 1, prices, n),
f(idx + 1, 0, prices, n));
}
else {
profit = Math.Max(prices[idx] + f(idx + 2, 0, prices, n),
f(idx + 1, 1, prices, n));
}
return profit;
}
public static int maxProfit( int [] prices, int n) {
return f(0, 0, prices, n);
}
public static void Main() {
int [] price = { 2, 4, 5, 0, 2 };
int n = price.Length;
Console.WriteLine(maxProfit(price, n));
}
}
|
Javascript
function f(idx, buy, prices, n) {
if (idx >= n) {
return 0;
}
let profit = 0;
if (buy == 0) {
profit = Math.max(-prices[idx] + f(idx + 1, 1, prices, n),
f(idx + 1, 0, prices, n));
}
else {
profit = Math.max(prices[idx] + f(idx + 2, 0, prices, n),
f(idx + 1, 1, prices, n));
}
return profit;
}
function maxProfit(prices, n) {
return f(0, 0, prices, n);
}
const price = [2, 4, 5, 0, 2];
const n = price.length;
console.log(maxProfit(price, n));
|
Time Complexity : O(2^N)
Auxiliary Space : O(N)
Memoization DP Â Approach:
One more way we can approach this problem is by considering buying and selling as two different states of the dp.
C++
#include <bits/stdc++.h>
using namespace std;
int f( int idx, int buy, int prices[],
vector<vector< int > >& dp, int n)
{
if (idx >= n) {
return 0;
}
if (dp[idx][buy] != -1) {
return dp[idx][buy];
}
int profit = 0;
if (buy == 0) {
dp[idx][buy] = profit = max(
-prices[idx] + f(idx + 1, 1, prices, dp, n),
f(idx + 1, 0, prices, dp, n));
}
else {
dp[idx][buy] = profit = max(
prices[idx] + f(idx + 2, 0, prices, dp, n),
f(idx + 1, 1, prices, dp, n));
}
return profit;
}
int maxProfit( int prices[], int n)
{
vector<vector< int > > dp(n, vector< int >(2, -1));
return f(0, 0, prices, dp, n);
}
int main()
{
int price[] = { 2, 4, 5, 0, 2 };
int n = sizeof (price) / sizeof (price[0]);
cout << maxProfit(price, n) << endl;
return 0;
}
|
Java
import java.util.*;
public class Main {
static int f( int idx, int buy, int [] prices,
List<List<Integer> > dp, int n)
{
if (idx >= n) {
return 0 ;
}
if (dp.get(idx).get(buy) != - 1 ) {
return dp.get(idx).get(buy);
}
int profit = 0 ;
if (buy == 0 ) {
dp.get(idx).set(
buy, profit = Math.max(
-prices[idx]
+ f(idx + 1 , 1 , prices, dp, n),
f(idx + 1 , 0 , prices, dp, n)));
}
else {
dp.get(idx).set(
buy, profit = Math.max(
prices[idx]
+ f(idx + 2 , 0 , prices, dp, n),
f(idx + 1 , 1 , prices, dp, n)));
}
return profit;
}
static int maxProfit( int [] prices, int n)
{
List<List<Integer> > dp = new ArrayList<>();
for ( int i = 0 ; i < n; i++) {
dp.add( new ArrayList<>(Arrays.asList(- 1 , - 1 )));
}
return f( 0 , 0 , prices, dp, n);
}
public static void main(String[] args)
{
int [] price = { 2 , 4 , 5 , 0 , 2 };
int n = price.length;
System.out.println(maxProfit(price, n));
}
}
|
Python3
from typing import List
def f(idx: int , buy: int , prices: List [ int ],
dp: List [ List [ int ]], n: int ) - > int :
if idx > = n:
return 0
if dp[idx][buy] ! = - 1 :
return dp[idx][buy]
profit = 0
if buy = = 0 :
dp[idx][buy] = profit = max ( - prices[idx] + f(idx + 1 , 1 , prices, dp, n),
f(idx + 1 , 0 , prices, dp, n))
else :
dp[idx][buy] = profit = max (prices[idx] + f(idx + 2 , 0 , prices, dp, n),
f(idx + 1 , 1 , prices, dp, n))
return profit
def maxProfit(prices: List [ int ], n: int ) - > int :
dp = [[ - 1 , - 1 ] for i in range (n)]
return f( 0 , 0 , prices, dp, n)
if __name__ = = '__main__' :
price = [ 2 , 4 , 5 , 0 , 2 ]
n = len (price)
print (maxProfit(price, n))
|
C#
using System;
class GFG
{
static int F( int idx, int buy, int [] prices, int [][] dp, int n)
{
if (idx >= n)
{
return 0;
}
if (dp[idx][buy] != -1)
{
return dp[idx][buy];
}
int profit = 0;
if (buy == 0)
{
dp[idx][buy] = profit = Math.Max(
-prices[idx] + F(idx + 1, 1, prices, dp, n),
F(idx + 1, 0, prices, dp, n));
}
else
{
dp[idx][buy] = profit = Math.Max(
prices[idx] + F(idx + 2, 0, prices, dp, n),
F(idx + 1, 1, prices, dp, n));
}
return profit;
}
static int MaxProfit( int [] prices, int n)
{
int [][] dp = new int [n][];
for ( int i = 0; i < n; i++)
{
dp[i] = new int [2];
dp[i][0] = dp[i][1] = -1;
}
return F(0, 0, prices, dp, n);
}
static void Main()
{
int [] price = { 2, 4, 5, 0, 2 };
int n = price.Length;
Console.WriteLine(MaxProfit(price, n));
}
}
|
Javascript
function maxProfit(prices) {
const n = prices.length;
const dp = new Array(n).fill().map(() => new Array(2).fill(-1));
function f(idx, buy) {
if (idx >= n) {
return 0;
}
if (dp[idx][buy] !== -1) {
return dp[idx][buy];
}
let profit = 0;
if (buy === 0) {
dp[idx][buy] = profit = Math.max(
-prices[idx] + f(idx + 1, 1),
f(idx + 1, 0)
);
}
else {
dp[idx][buy] = profit = Math.max(
prices[idx] + f(idx + 2, 0),
f(idx + 1, 1)
);
}
return profit;
}
return f(0, 0);
}
const price = [2, 4, 5, 0, 2];
console.log(maxProfit(price));
|
Time Complexity : O(N)
Auxiliary Space : O(N)
One Pass Method:
Steps:
- First, Initialize the variables for buying, selling, and their previous values.
- second, traverse the array and compute the max profit that can be made by buying and selling the stocks.
- Stores the previous value of buy before it is updated.
- Compute the max profit that can be made by buying the stock on the current day or not buying it.
- Again, store the previous value of sell before it is updated.
- Compute the max profit that can be made by selling the stock on the current day or not selling it.
- last return the max profit.
Below is code implementation for the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int maxProfit( int arr[], int n) {
int buy = INT_MIN, prev_sell = 0, sell = 0, prev_buy;
for ( int i = 0; i < n; i++) {
prev_buy = buy;
buy = max(prev_sell - arr[i], prev_buy);
prev_sell = sell;
sell = max(prev_buy + arr[i], prev_sell);
}
return sell;
}
int main() {
int arr[] = {2, 4, 5, 0, 2};
int n = sizeof (arr) / sizeof (arr[0]);
cout << maxProfit(arr, n) << endl;
return 0;
}
|
C
#include <stdio.h>
#include <limits.h>
int maxProfit( int arr[], int n) {
int buy = INT_MIN, prev_sell = 0, sell = 0, prev_buy;
for ( int i = 0; i < n; i++) {
prev_buy = buy;
buy = (prev_sell - arr[i] > prev_buy) ? prev_sell - arr[i] : prev_buy;
prev_sell = sell;
sell = (prev_buy + arr[i] > prev_sell) ? prev_buy + arr[i] : prev_sell;
}
return sell;
}
int main() {
int arr[] = {2, 4, 5, 0, 2};
int n = sizeof (arr) / sizeof (arr[0]);
printf ( "%d\n" , maxProfit(arr, n));
return 0;
}
|
Java
public class Main {
public static int maxProfit( int [] prices) {
int buy = Integer.MIN_VALUE;
int prevSell = 0 ;
int sell = 0 ;
int prevBuy;
for ( int price : prices) {
prevBuy = buy;
buy = Math.max(prevSell - price, prevBuy);
prevSell = sell;
sell = Math.max(prevBuy + price, prevSell);
}
return sell;
}
public static void main(String[] args) {
int [] prices = { 2 , 4 , 5 , 0 , 2 };
System.out.println(maxProfit(prices));
}
}
|
Python3
def max_profit(arr):
buy = float ( '-inf' )
prev_sell = 0
sell = 0
prev_buy = 0
for price in arr:
prev_buy = buy
buy = max (prev_sell - price, prev_buy)
prev_sell = sell
sell = max (prev_buy + price, prev_sell)
return sell
arr = [ 2 , 4 , 5 , 0 , 2 ]
print (max_profit(arr))
|
C#
using System;
class MainClass {
public static int MaxProfit( int [] prices) {
int buy = int .MinValue;
int prevSell = 0;
int sell = 0;
int prevBuy;
foreach ( int price in prices) {
prevBuy = buy;
buy = Math.Max(prevSell - price, prevBuy);
prevSell = sell;
sell = Math.Max(prevBuy + price, prevSell);
}
return sell;
}
public static void Main ( string [] args) {
int [] prices = {2, 4, 5, 0, 2};
Console.WriteLine(MaxProfit(prices));
}
}
|
Javascript
function maxProfit(arr) {
let buy = -Infinity;
let prevSell = 0;
let sell = 0;
let prevBuy = 0;
for (let i = 0; i < arr.length; i++) {
prevBuy = buy;
buy = Math.max(prevSell - arr[i], prevBuy);
prevSell = sell;
sell = Math.max(prevBuy + arr[i], prevSell);
}
return sell;
}
function main() {
const arr = [2, 4, 5, 0, 2];
const result = maxProfit(arr);
console.log(result);
}
main();
|
PHP
<?php
function maxProfit( $arr ) {
$buy = PHP_INT_MIN;
$prev_sell = 0;
$sell = 0;
$prev_buy = 0;
foreach ( $arr as $value ) {
$prev_buy = $buy ;
$buy = max( $prev_sell - $value , $prev_buy );
$prev_sell = $sell ;
$sell = max( $prev_buy + $value , $prev_sell );
}
return $sell ;
}
$arr = array (2, 4, 5, 0, 2);
$result = maxProfit( $arr );
echo $result . "\n" ;
?>
|
Time Complexity: O(n) because it performs a single pass over the input array of size n.
Auxiliary Space: O(1)Â
Share your thoughts in the comments
Please Login to comment...