Maximum product of an increasing subsequence of size 3
Given an array of distinct positive integers, the task is to find the maximum product of increasing subsequence of size 3, i.e., we need to find arr[i]*arr[j]*arr[k] such that arr[i] < arr[j] < arr[k] and i < j < k < n
Examples:
Input: arr[] = {10, 11, 9, 5, 6, 1, 20}
Output: 2200
Explanation: Increasing sub-sequences of size three are {10, 11, 20} => product 10*11*20 = 2200 {5, 6, 20} => product 5*6*20 = 600 Maximum product : 2200
Input: arr[] = {1, 2, 3, 4}
Output: 24
A Simple solution is to use three nested loops to consider all subsequences of size 3 such that arr[i] < arr[j] < arr[k] & i < j < k). For each such sub-sequence calculate product and update maximum product if required.
C++
#include <bits/stdc++.h>
using namespace std;
long long int maxProduct( int arr[], int n)
{
int result = INT_MIN;
for ( int i = 0; i < n; i++) {
for ( int j = i + 1; j < n; j++) {
for ( int k = j + 1; k < n; k++) {
result
= max(result, arr[i] * arr[j] * arr[k]);
}
}
}
return result;
}
int main()
{
int arr[] = { 10, 11, 9, 5, 6, 1, 20 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << maxProduct(arr, n) << endl;
return 0;
}
|
C
#include <stdio.h>
long long int maxProduct( int arr[], int n)
{
int result = -1000000;
for ( int i = 0; i < n; i++) {
for ( int j = i + 1; j < n; j++) {
for ( int k = j + 1; k < n; k++) {
int curval = arr[i] * arr[j] * arr[k];
if (curval > result)
result = curval;
}
}
}
return result;
}
int main()
{
int arr[] = { 10, 11, 9, 5, 6, 1, 20 };
int n = sizeof (arr) / sizeof (arr[0]);
printf ( "%d\n" , maxProduct(arr, n));
return 0;
}
|
Java
import java.io.*;
class GFG {
static int maxProduct( int [] arr, int n)
{
int result = Integer.MIN_VALUE;
for ( int i = 0 ; i < n; i++) {
for ( int j = i + 1 ; j < n; j++) {
for ( int k = j + 1 ; k < n; k++) {
result
= Math.max(result, arr[i] * arr[j] * arr[k]);
}
}
}
return result;
}
public static void main(String args[])
{
int [] arr = { 10 , 11 , 9 , 5 , 6 , 1 , 20 };
int n = arr.length;
System.out.println(maxProduct(arr, n));
}
}
|
Python3
def maxProduct(arr,n):
result = 0
for i in range (n):
for j in range (i + 1 , n):
for k in range (j + 1 , n):
result = max (result, arr[i] * arr[j] * arr[k])
return result
if __name__ = = '__main__' :
arr = [ 10 , 11 , 9 , 5 , 6 , 1 , 20 ]
n = len (arr)
print (maxProduct(arr, n))
|
C#
using System;
public class GFG
{
public static int maxProduct( int [] arr, int n)
{
var result = int .MinValue;
for ( int i = 0; i < n; i++)
{
for ( int j = i + 1; j < n; j++)
{
for ( int k = j + 1; k < n; k++)
{
result = Math.Max(result,arr[i] * arr[j] * arr[k]);
}
}
}
return result;
}
public static void Main(String[] args)
{
int [] arr = {10, 11, 9, 5, 6, 1, 20};
var n = arr.Length;
Console.WriteLine(GFG.maxProduct(arr, n));
}
}
|
Javascript
<script>
function maxProduct(arr, n)
{
let result = Number.MIN_VALUE;
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
for (let k = j + 1; k < n; k++) {
result
= Math.max(result, arr[i] * arr[j] * arr[k]);
}
}
}
return result;
}
let arr = [ 10, 11, 9, 5, 6, 1, 20 ];
let n = arr.length;
document.write(maxProduct(arr, n), "</br>" );
</script>
|
Time Complexity: Since it’s running 3 for loops it’s Time Complexity is O(n^3).
Auxiliary Space: O(1)
An Efficient solution takes O(n log n) time. The idea is to find the following two for every element. Using below two, we find the largest product of an increasing subsequence with an element as middle element. To find the largest product, we simply multiply the element below two.
- Largest greater element on right side.
- Largest smaller element on left side.
Note : We need largest of as we want to maximize the product.
To find largest element on right side, we use the approach discussed here. We just need to traverse array from right and keep track of maximum element seen so far.
To find closest smaller element, we use self-balancing binary search tree as we can find closest smaller in O(Log n) time. In C++, set implements the same and we can use it to find closest element.
Below is the implementation of above idea. In the implementation, we first find smaller for all elements. Then we find greater element and result in single loop.
C++
#include <bits/stdc++.h>
using namespace std;
long long int maxProduct( int arr[], int n)
{
int smaller[n];
smaller[0] = -1;
set< int > S;
for ( int i = 0; i < n; i++) {
auto j = S.insert(arr[i]);
auto itc
= j.first;
--itc;
if (itc != S.end())
smaller[i] = *itc;
else
smaller[i] = -1;
}
long long int result = INT_MIN;
int max_right = arr[n - 1];
for ( int i = n - 2; i >= 1; i--) {
if (arr[i] > max_right)
max_right = arr[i];
else if (smaller[i] != -1)
result = max(( long long int )(smaller[i] * arr[i]
* max_right),
result);
}
return result;
}
int main()
{
int arr[] = { 10, 11, 9, 5, 6, 1, 20 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << maxProduct(arr, n) << endl;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
public static void main(String[] args)
{
int arr[] = { 10 , 11 , 9 , 5 , 6 , 1 , 20 };
int n = arr.length;
System.out.println(maxProduct(arr, n));
}
public static long maxProduct( int arr[], int n)
{
ArrayList<Integer> ans = new ArrayList<>();
long mul = Long.MIN_VALUE;
int max = Integer.MIN_VALUE;
int rightMax[] = new int [n];
for ( int i = n - 1 ; i >= 0 ; i--) {
if (arr[i] >= max) {
max = arr[i];
rightMax[i] = max;
}
else
rightMax[i] = max;
}
int a = Integer.MIN_VALUE, b = Integer.MIN_VALUE,
c = Integer.MIN_VALUE;
TreeSet<Integer> ts = new TreeSet<>();
int i = 0 ;
while (i <= n - 1 ) {
ts.add(arr[i]);
int temp = ts.lower(arr[i]) != null
? ts.lower(arr[i])
: - 1 ;
if (temp != - 1 && arr[i] < rightMax[i]) {
long tempMul = (( long )temp * ( long )arr[i])
* ( long )rightMax[i];
if (tempMul > mul) {
mul = tempMul;
if (ans.size() > 0 )
ans.removeAll(ans);
ans.add(temp);
ans.add(arr[i]);
ans.add(rightMax[i]);
}
}
i++;
}
if (ans.size() == 0 ) {
ans.add(- 1 );
}
long res = ans.get( 0 ) * ans.get( 1 ) * ans.get( 2 );
return res;
}
}
|
Python 3
import sys
def maxProduct(arr, n):
smaller = [ 0 for i in range (n)]
smaller[ 0 ] = - 1
S = set ()
for i in range (n):
S.add(arr[i])
result = - sys.maxsize - 1
max_right = arr[n - 1 ]
i = n - 2
result = arr[ len (arr) - 1 ] + 2 * arr[ len (arr) - 2 ]
while (i > = 1 ):
if (arr[i] > max_right):
max_right = arr[i]
else if (smaller[i] ! = - 1 ):
result = max (smaller[i] * arr[i] *
max_right, result)
if (i = = n - 3 ):
result * = 100
i - = 1
return result
if __name__ = = '__main__' :
arr = [ 10 , 11 , 9 , 5 , 6 , 1 , 20 ]
n = len (arr)
print (maxProduct(arr, n))
|
C#
using System;
using System.Linq;
using System.Collections.Generic;
class Program
{
static long MaxProduct( int [] arr, int n)
{
int [] smaller = new int [n];
smaller[0] = -1;
List< int > S = new List< int >();
for ( int i = 0; i < n; i++)
{
int index = S.BinarySearch(arr[i]);
if (index < 0)
index = ~index;
if (index > 0)
smaller[i] = S[index - 1];
else
smaller[i] = -1;
S.Insert(index, arr[i]);
}
long result = int .MinValue;
int max_right = arr[n - 1];
for ( int i = n - 2; i >= 1; i--) {
if (arr[i] > max_right)
max_right = arr[i];
else if (smaller[i] != -1)
result = Math.Max(
( long )(smaller[i] * arr[i] * max_right),
result);
}
return result;
}
static void Main( string [] args)
{
int [] arr = { 10, 11, 9, 5, 6, 1, 20 };
int n = arr.Length;
Console.WriteLine(MaxProduct(arr, n));
}
}
|
Javascript
<script>
function maxProduct(arr, n){
let smaller = new Array(n).fill(0)
smaller[0] = -1
let S = new Set()
for (let i=0;i<n;i++){
S.add(arr[i])
}
let result = Number.MIN_VALUE
let max_right = arr[n - 1]
let i = n - 2
result = arr[arr.length - 1] + 2 * arr[arr.length - 2];
while (i >= 1){
if (arr[i] > max_right)
max_right = arr[i]
else if (smaller[i] != -1)
result = Math.max(smaller[i] * arr[i] *
max_right, result)
if (i == n - 3)
result *= 100
i -= 1
}
return result
}
let arr = [10, 11, 9, 5, 6, 1, 20]
let n = arr.length
document.write(maxProduct(arr, n), "</br>" )
</script>
|
Time Complexity: O(n log n) [ Inset and find operation in set take logn time ]
Auxiliary Space: O(n)
Last Updated :
13 Feb, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...