Given an array arr[] of positive integers representing prices of stocks and an integer transactionFee, the task is to find the maximum profit possible after buying and selling stocks any number of times and giving the transaction fee for each transaction.
Examples:
Input: arr[] = {6, 1, 7, 2, 8, 4}, transactionFee = 2
Output: 8
Explanation:
A maximum profit of 8 can be obtained by two transactions.
Transaction 1: Buy at price 1 and sell at price 7. Profit = 7 – 1 – 2 = 4.
Transaction 2: Buy at price 2 and sell at price 8. Profit = 8 – 2 – 2 = 4.
Therefore, total profit = 4 + 4 = 8, which is the maximum possible.
Input: arr[] = {2, 7, 5, 9, 6, 4}, transactionFee = 1
Output: 7
Naive Approach: Refer to the previous post for the simplest approach to solve the problem.
Time Complexity: O(N2)
Auxiliary Space: O(1)
Recursive Approach:
If we purchase at an index, we have the option to either sell or pass on the following index.
If we choose to sell, we will incur a transaction fee, but if we opt to pass, we can still sell or pass on
the next index. On the other hand, if we sell at an index, our only options are to buy or pass on the
next index and so on.
C++
#include <bits/stdc++.h>
using namespace std;
int f( int idx, int n, int buy, int prices[], int fee)
{
if (idx == n) {
return 0;
}
int profit = 0;
if (buy == 0) {
profit = max(-prices[idx]
+ f(idx + 1, n, 1, prices, fee),
f(idx + 1, n, 0, prices, fee));
}
else {
profit = max(prices[idx] - fee
+ f(idx + 1, n, 0, prices, fee),
f(idx + 1, n, 1, prices, fee));
}
return profit;
}
int MaxProfit( int prices[], int n, int fee)
{
return f(0, n, 0, prices, fee);
}
int main()
{
int arr[] = { 6, 1, 7, 2, 8, 4 };
int n = sizeof (arr) / sizeof (arr[0]);
int transactionFee = 2;
cout << MaxProfit(arr, n, transactionFee);
return 0;
}
|
Java
import java.io.*;
class GFG {
static int f( int idx, int n, int buy, int prices[],
int fee)
{
if (idx == n) {
return 0 ;
}
int profit = 0 ;
if (buy == 0 ) {
profit = Math.max(
-prices[idx]
+ f(idx + 1 , n, 1 , prices, fee),
f(idx + 1 , n, 0 , prices, fee));
}
else {
profit = Math.max(
prices[idx] - fee
+ f(idx + 1 , n, 0 , prices, fee),
f(idx + 1 , n, 1 , prices, fee));
}
return profit;
}
static int MaxProfit( int prices[], int n, int fee)
{
return f( 0 , n, 0 , prices, fee);
}
public static void main(String[] args)
{
int arr[] = { 6 , 1 , 7 , 2 , 8 , 4 };
int n = arr.length;
int transactionFee = 2 ;
System.out.println(
MaxProfit(arr, n, transactionFee));
}
}
|
Python3
def f(idx, n, buy, prices, fee):
if idx = = n:
return 0
profit = 0
if buy = = 0 :
profit = max ( - prices[idx]
+ f(idx + 1 , n, 1 , prices, fee),
f(idx + 1 , n, 0 , prices, fee))
else :
profit = max (prices[idx] - fee
+ f(idx + 1 , n, 0 , prices, fee),
f(idx + 1 , n, 1 , prices, fee))
return profit
def MaxProfit(prices, n, fee):
return f( 0 , n, 0 , prices, fee)
if __name__ = = '__main__' :
arr = [ 6 , 1 , 7 , 2 , 8 , 4 ]
n = len (arr)
transactionFee = 2
print (MaxProfit(arr, n, transactionFee))
|
C#
using System;
public class GFG {
static int f( int idx, int n, int buy, int [] prices,
int fee)
{
if (idx == n) {
return 0;
}
int profit = 0;
if (buy == 0) {
profit = Math.Max(
-prices[idx]
+ f(idx + 1, n, 1, prices, fee),
f(idx + 1, n, 0, prices, fee));
}
else {
profit = Math.Max(
prices[idx] - fee
+ f(idx + 1, n, 0, prices, fee),
f(idx + 1, n, 1, prices, fee));
}
return profit;
}
static int MaxProfit( int [] prices, int n, int fee)
{
return f(0, n, 0, prices, fee);
}
static public void Main()
{
int [] arr = { 6, 1, 7, 2, 8, 4 };
int n = arr.Length;
int transactionFee = 2;
Console.WriteLine(
MaxProfit(arr, n, transactionFee));
}
}
|
Javascript
function f(idx, n, buy, prices, fee) {
if (idx == n) {
return 0;
}
let profit = 0;
if (buy == 0) {
profit = Math.max(-prices[idx] + f(idx + 1, n, 1, prices, fee), f(idx + 1, n, 0, prices, fee));
}
else {
profit = Math.max(prices[idx] - fee + f(idx + 1, n, 0, prices, fee), f(idx + 1, n, 1, prices, fee));
}
return profit;
}
function maxProfit(prices, fee) {
const n = prices.length;
return f(0, n, 0, prices, fee);
}
const arr = [6, 1, 7, 2, 8, 4];
const transactionFee = 2;
console.log(maxProfit(arr, transactionFee));
|
Time complexity: O(2^N), where n is the number of elements in the input array “prices”. This is because for each index, the function has two possibilities (buy or not buy, or sell or not sell) and it calls itself recursively for each possibility.
Auxiliary Space: O(N) Recursive Stack Space
Memoization Approach:
C++
#include <bits/stdc++.h>
using namespace std;
int f( int idx, int n, int buy, int prices[],
vector<vector< int > >& dp, int fee)
{
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, n, 1, prices, dp, fee),
f(idx + 1, n, 0, prices, dp, fee));
}
else {
dp[idx][buy] = profit
= max(prices[idx] - fee
+ f(idx + 1, n, 0, prices, dp, fee),
f(idx + 1, n, 1, prices, dp, fee));
}
return profit;
}
int MaxProfit( int prices[], int n, int fee)
{
vector<vector< int > > dp(n, vector< int >(2, -1));
return f(0, n, 0, prices, dp, fee);
}
int main()
{
int arr[] = { 6, 1, 7, 2, 8, 4 };
int n = sizeof (arr) / sizeof (arr[0]);
int transactionFee = 2;
cout << MaxProfit(arr, n, transactionFee);
return 0;
}
|
Java
import java.util.*;
public class Main {
public static int f( int idx, int n, int buy, int [] prices,
List<List<Integer>> dp, int fee) {
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 , n, 1 , prices, dp, fee),
f(idx + 1 , n, 0 , prices, dp, fee)));
}
else {
dp.get(idx).set(buy, profit
= Math.max(prices[idx] - fee
+ f(idx + 1 , n, 0 , prices, dp, fee),
f(idx + 1 , n, 1 , prices, dp, fee)));
}
return profit;
}
public static int MaxProfit( int [] prices, int n, int fee) {
List<List<Integer>> dp = new ArrayList<>();
for ( int i = 0 ; i < n; i++) {
dp.add( new ArrayList<>(Arrays.asList(- 1 , - 1 )));
}
return f( 0 , n, 0 , prices, dp, fee);
}
public static void main(String[] args) {
int [] arr = { 6 , 1 , 7 , 2 , 8 , 4 };
int n = arr.length;
int transactionFee = 2 ;
System.out.println(MaxProfit(arr, n, transactionFee));
}
}
|
Python
def maxProfit(prices, fee):
n = len (prices)
dp = [[ 0 ] * 2 for _ in range (n)]
dp[ 0 ][ 0 ] = 0
dp[ 0 ][ 1 ] = - prices[ 0 ]
for i in range ( 1 , n):
dp[i][ 0 ] = max (dp[i - 1 ][ 0 ], dp[i - 1 ][ 1 ] + prices[i] - fee)
dp[i][ 1 ] = max (dp[i - 1 ][ 1 ], dp[i - 1 ][ 0 ] - prices[i])
return dp[n - 1 ][ 0 ]
prices = [ 6 , 1 , 7 , 2 , 8 , 4 ]
transaction_fee = 2
print (maxProfit(prices, transaction_fee))
|
C#
using System;
class Program
{
static int MaxProfit( int [] prices, int fee)
{
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 F(0, n, 0, prices, dp, fee);
}
static int F( int idx, int n, int buy, int [] prices, int [,] dp, int fee)
{
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, n, 1, prices, dp, fee),
F(idx + 1, n, 0, prices, dp, fee));
}
else
{
dp[idx, buy] = profit = Math.Max(prices[idx] - fee +
F(idx + 1, n, 0, prices, dp, fee),
F(idx + 1, n, 1, prices, dp, fee));
}
return profit;
}
static void Main()
{
int [] arr = { 6, 1, 7, 2, 8, 4 };
int transactionFee = 2;
int maxProfit = MaxProfit(arr, transactionFee);
Console.WriteLine(maxProfit);
}
}
|
Javascript
function maxProfit(prices, fee) {
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] - fee + f(idx + 1, 0),
f(idx + 1, 1)
);
}
return profit;
}
return f(0, 0);
}
function main() {
const arr = [6, 1, 7, 2, 8, 4];
const transactionFee = 2;
console.log(maxProfit(arr, transactionFee));
}
main();
|
Time Complexity: O(N)
Space Complexity: O(N)
Efficient Approach: To optimize the above approach, the idea is to use Dynamic Programming. For each day, maintain the maximum profit, if stocks are bought on that day (buy) and the maximum profit if all stocks are sold on that day (sell). For each day, update buy and sell using the following relations:
buy = max(sell – arr[i], buy)
sell = max(buy +arr[i] – transactionFee, sell)
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int MaxProfit( int arr[], int n,
int transactionFee)
{
int buy = -arr[0];
int sell = 0;
for ( int i = 1; i < n; i++) {
int temp = buy;
buy = max(buy, sell - arr[i]);
sell = max(sell,
temp + arr[i] - transactionFee);
}
return max(sell, buy);
}
int main()
{
int arr[] = { 6, 1, 7, 2, 8, 4 };
int n = sizeof (arr) / sizeof (arr[0]);
int transactionFee = 2;
cout << MaxProfit(arr, n, transactionFee);
return 0;
}
|
Java
import java.io.*;
class GFG
{
static int MaxProfit( int arr[], int n,
int transactionFee)
{
int buy = -arr[ 0 ];
int sell = 0 ;
for ( int i = 1 ; i < n; i++) {
int temp = buy;
buy = Math.max(buy, sell - arr[i]);
sell = Math.max(sell,
temp + arr[i] - transactionFee);
}
return Math.max(sell, buy);
}
public static void main(String[] args)
{
int arr[] = { 6 , 1 , 7 , 2 , 8 , 4 };
int n = arr.length;
int transactionFee = 2 ;
System.out.println(
MaxProfit(arr, n, transactionFee));
}
}
|
Python3
def MaxProfit(arr, n, transactionFee):
buy = - arr[ 0 ]
sell = 0
for i in range ( 1 , n, 1 ):
temp = buy
buy = max (buy, sell - arr[i])
sell = max (sell, temp + arr[i] -
transactionFee)
return max (sell, buy)
if __name__ = = '__main__' :
arr = [ 6 , 1 , 7 , 2 , 8 , 4 ]
n = len (arr)
transactionFee = 2
print (MaxProfit(arr, n, transactionFee))
|
C#
using System;
class GFG {
static int MaxProfit( int [] arr, int n,
int transactionFee)
{
int buy = -arr[0];
int sell = 0;
for ( int i = 1; i < n; i++) {
int temp = buy;
buy = Math.Max(buy, sell - arr[i]);
sell = Math.Max(sell,
temp + arr[i] - transactionFee);
}
return Math.Max(sell, buy);
}
public static void Main()
{
int [] arr = { 6, 1, 7, 2, 8, 4 };
int n = arr.Length;
int transactionFee = 2;
Console.WriteLine(
MaxProfit(arr, n, transactionFee));
}
}
|
Javascript
<script>
function MaxProfit(arr, n, transactionFee)
{
let buy = -arr[0];
let sell = 0;
for (let i = 1; i < n; i++)
{
let temp = buy;
buy = Math.max(buy, sell - arr[i]);
sell = Math.max(sell,
temp + arr[i] - transactionFee);
}
return Math.max(sell, buy);
}
let arr = [ 6, 1, 7, 2, 8, 4 ];
let n = arr.length;
let transactionFee = 2;
document.write(
MaxProfit(arr, n, transactionFee));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(1)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!