Given an array arr[], where arr[i] represents the price of the i-th product, calculate the total profit as follows:
For each product, find the first product to its right whose price is greater than or equal to the current product's price. If such a product exists, the profit for the current product is the difference between their prices. Otherwise, the profit is equal to the current product's price.
Return the total profit obtained by summing the profit for all products.
Examples:
Input: arr[] = [5, 4, 6, 2, 1]
Output: 12
Explanation:
For 5, the first greater or equal price is 6, profit = 6 - 5 = 1
For 4, the first greater or equal price is 6, profit = 6 - 4 = 2
For 6, there is no greater or equal price to its right, profit = 6
For 2, there is no greater or equal price to its right, profit = 2
For 1, there is no greater or equal price to its right, profit = 1
Total profit = 1 + 2 + 6 + 2 + 1 = 12.Input: arr[] = [1, 2, 3, 4]
Output: 7
Explanation:
For 1, the first greater or equal price to its right is 2, profit = 2 - 1 = 1
For 2, the first greater or equal price to its right is 3, profit = 3 - 2 = 1
For 3, the first greater or equal price to its right is 4, profit = 4 - 3 = 1
For 4, there is no greater or equal price to its right, profit = 4
Total profit = 1 + 1 + 1 + 4 = 7.
Table of Content
[Naive Approach] Check First Greater or Equal Element for Every Product - O(n ^ 2) Time and O(1) Space
The idea is to process each product independently. For every price, scan all products to its right until the first greater or equal price is found. If found, add the difference to the answer; otherwise, add the product's own price.
Working of Approach:
- Traverse every product one by one.
- For each product, search linearly on its right.
- If the first greater or equal price is found, add their difference.
- Otherwise, add the current price itself.
- Return the total accumulated profit.
#include <iostream>
#include <vector>
using namespace std;
int profit(vector<int> &arr)
{
int n = arr.size();
int res = 0;
// Traverse every product.
for (int i = 0; i < n; i++)
{
bool found = false;
// Find the first greater or equal price on the right.
for (int j = i + 1; j < n; j++)
{
if (arr[j] >= arr[i])
{
// Add the profit for the current product.
res += (arr[j] - arr[i]);
found = true;
break;
}
}
// If no greater or equal price exists,
// add the current product's price.
if (!found)
res += arr[i];
}
// Return the total profit.
return res;
}
int main()
{
vector<int> arr = {1, 2, 3, 4};
cout << profit(arr);
return 0;
}
import java.util.*;
class GFG {
public int profit(int[] arr)
{
int n = arr.length;
int res = 0;
// Traverse every product.
for (int i = 0; i < n; i++) {
boolean found = false;
// Find the first greater or equal price on the
// right.
for (int j = i + 1; j < n; j++) {
if (arr[j] >= arr[i]) {
// Add the profit for the current
// product.
res += (arr[j] - arr[i]);
found = true;
break;
}
}
// If no greater or equal price exists,
// add the current product's price.
if (!found)
res += arr[i];
}
// Return the total profit.
return res;
}
public static void main(String[] args)
{
int[] arr = { 1, 2, 3, 4 };
GFG obj = new GFG();
System.out.println(obj.profit(arr));
}
}
def profit(arr):
n = len(arr)
res = 0
# Traverse every product.
for i in range(n):
found = False
# Find the first greater or equal price on the right.
for j in range(i + 1, n):
if arr[j] >= arr[i]:
# Add the profit for the current product.
res += (arr[j] - arr[i])
found = True
break
# If no greater or equal price exists,
# add the current product's price.
if not found:
res += arr[i]
# Return the total profit.
return res
if __name__ == "__main__":
arr = [1, 2, 3, 4]
print(profit(arr))
using System;
class GFG {
public int profit(int[] arr)
{
int n = arr.Length;
int res = 0;
// Traverse every product.
for (int i = 0; i < n; i++) {
bool found = false;
// Find the first greater or equal price on the
// right.
for (int j = i + 1; j < n; j++) {
if (arr[j] >= arr[i]) {
// Add the profit for the current
// product.
res += (arr[j] - arr[i]);
found = true;
break;
}
}
// If no greater or equal price exists,
// add the current product's price.
if (!found)
res += arr[i];
}
// Return the total profit.
return res;
}
static void Main()
{
int[] arr = { 1, 2, 3, 4 };
GFG obj = new GFG();
Console.WriteLine(obj.profit(arr));
}
}
function profit(arr)
{
let n = arr.length;
let res = 0;
// Traverse every product.
for (let i = 0; i < n; i++) {
let found = false;
// Find the first greater or equal price on the
// right.
for (let j = i + 1; j < n; j++) {
if (arr[j] >= arr[i]) {
// Add the profit for the current product.
res += (arr[j] - arr[i]);
found = true;
break;
}
}
// If no greater or equal price exists,
// add the current product's price.
if (!found)
res += arr[i];
}
// Return the total profit.
return res;
}
// Driver Code
let arr = [ 1, 2, 3, 4 ];
console.log(profit(arr));
Output
7
[Expected Approach] Using Monotonic Stack (Left to Right) - O(n) Time and O(n) Space
The idea is to maintain a monotonic decreasing stack of product prices whose first greater or equal price has not been found yet. Whenever a greater or equal price is encountered, compute its profit immediately and remove it from the stack.
Working of Approach:
- Traverse the array from left to right.
- Maintain a decreasing stack of unresolved prices.
- Pop all smaller or equal prices and add their profit immediately.
- Push the current price into the stack.
- After traversal, remaining prices have no greater or equal element, so add their own values.
Let us understand with an example:
Input: arr[] = [1, 2, 3, 4]
- Start with an empty stack. Push 1 into the stack.
- 2 is greater than 1, so profit is 2 - 1 = 1. Pop 1 and push 2.
- 3 is greater than 2, so profit is 3 - 2 = 1. Pop 2 and push 3.
- 4 is greater than 3, so profit is 4 - 3 = 1. Pop 3 and push 4.
- After traversal, 4 has no greater or equal element on its right, so add 4 itself. Total profit = 1 + 1 + 1 + 4 = 7.
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
int profit(vector<int> &arr)
{
stack<int> st;
int res = 0;
for (int price : arr)
{
// Current price is the next greater/equal element
// for all smaller or equal prices on the stack.
while (!st.empty() && price >= st.top())
{
res += (price - st.top());
st.pop();
}
// Current element may find it's answer later.
st.push(price);
}
// Remaining elements have no greater/equal element on the right.
// Their profit is equal to their own value.
while (!st.empty())
{
res += st.top();
st.pop();
}
return res;
}
int main()
{
vector<int> arr = {1, 2, 3, 4};
cout << profit(arr);
return 0;
}
import java.util.*;
class GFG {
public int profit(int[] arr)
{
Stack<Integer> st = new Stack<>();
int res = 0;
for (int price : arr) {
// Current price is the next greater/equal
// element for all smaller or equal prices on
// the stack.
while (!st.isEmpty() && price >= st.peek()) {
res += (price - st.peek());
st.pop();
}
// Current element may find its answer later.
st.push(price);
}
// Remaining elements have no greater/equal element
// on the right. Their profit is equal to their own
// value.
while (!st.isEmpty()) {
res += st.pop();
}
return res;
}
public static void main(String[] args)
{
int[] arr = { 1, 2, 3, 4 };
GFG obj = new GFG();
System.out.println(obj.profit(arr));
}
}
def profit(arr):
from collections import deque
st = deque()
res = 0
for price in arr:
# Current price is the next greater/equal element
# for all smaller or equal prices on the stack.
while st and price >= st[-1]:
res += (price - st.pop())
# Current element may find it's answer later.
st.append(price)
# Remaining elements have no greater/equal element on the right.
# Their profit is equal to their own value.
while st:
res += st.pop()
return res
if __name__ == "__main__":
arr = [1, 2, 3, 4]
print(profit(arr))
using System;
using System.Collections.Generic;
class GFG {
public int profit(int[] arr)
{
Stack<int> st = new Stack<int>();
int res = 0;
foreach(int price in arr)
{
// Current price is the next greater/equal
// element for all smaller or equal prices on
// the stack.
while (st.Count > 0 && price >= st.Peek()) {
res += (price - st.Peek());
st.Pop();
}
// Current element may find its answer later.
st.Push(price);
}
// Remaining elements have no greater/equal element
// on the right. Their profit is equal to their own
// value.
while (st.Count > 0) {
res += st.Pop();
}
return res;
}
static void Main()
{
int[] arr = { 1, 2, 3, 4 };
GFG obj = new GFG();
Console.WriteLine(obj.profit(arr));
}
}
function profit(arr)
{
let st = [];
let res = 0;
for (let price of arr) {
// Current price is the next greater/equal element
// for all smaller or equal prices on the stack.
while (st.length > 0
&& price >= st[st.length - 1]) {
res += (price - st.pop());
}
// Current element may find it's answer later.
st.push(price);
}
// Remaining elements have no greater/equal element on
// the right. Their profit is equal to their own value.
while (st.length > 0) {
res += st.pop();
}
return res;
}
// Driver Code
let arr = [ 1, 2, 3, 4 ];
console.log(profit(arr));
Output
7