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 : 2200Input: 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++ program to find maximum product of an increasing // subsequence of size 3 #include <bits/stdc++.h> using namespace std;
// Returns maximum product of an increasing subsequence of // size 3 in arr[0..n-1]. If no such subsequence exists, // then it returns INT_MIN long long int maxProduct( int arr[], int n)
{ int result = INT_MIN;
// T.C : O(n^3)
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;
} // Driver Program 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 program to find maximum product of an increasing // subsequence of size 3 #include <stdio.h> // Returns maximum product of an increasing subsequence of // size 3 in arr[0..n-1]. If no such subsequence exists, // then it returns INT_MIN long long int maxProduct( int arr[], int n)
{ int result = -1000000;
// T.C : O(n^3)
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;
} // Driver Program 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;
} |
/*package whatever //do not write package name here */ import java.io.*;
class GFG {
// Java program to find maximum product of an increasing
// subsequence of size 3 // Returns maximum product of an increasing subsequence of // size 3 in arr[0..n-1]. If no such subsequence exists, // then it returns INT_MIN static int maxProduct( int [] arr, int n)
{ int result = Integer.MIN_VALUE;
// T.C : O(n^3)
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;
} /* Driver program to test above function*/ 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));
} } // This code is contributed by shinjanpatra |
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))
# This code is contributed by 111arpit1
|
// Include namespace system using System;
public class GFG
{ // C# program to find maximum product of an increasing
// subsequence of size 3
// Returns maximum product of an increasing subsequence of
// size 3 in arr[0..n-1]. If no such subsequence exists,
// then it returns INT_MIN
public static int maxProduct( int [] arr, int n)
{
var result = int .MinValue;
// T.C : O(n^3)
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;
}
// Driver program to test above function
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));
}
} // This code is contributed by aadityaburujwale. |
<script> // JavaScript program to find maximum product of an increasing // subsequence of size 3 // Returns maximum product of an increasing subsequence of // size 3 in arr[0..n-1]. If no such subsequence exists, // then it returns INT_MIN function maxProduct(arr, n)
{ let result = Number.MIN_VALUE;
// T.C : O(n^3)
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;
} // Driver Program let arr = [ 10, 11, 9, 5, 6, 1, 20 ]; let n = arr.length; document.write(maxProduct(arr, n), "</br>" );
// This code is contributed by shinjanpatra </script> |
2200
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++ program to find maximum product of an increasing // subsequence of size 3 #include <bits/stdc++.h> using namespace std;
// Returns maximum product of an increasing subsequence of // size 3 in arr[0..n-1]. If no such subsequence exists, // then it returns INT_MIN long long int maxProduct( int arr[], int n)
{ // An array ti store closest smaller element on left
// side of every element. If there is no such element
// on left side, then smaller[i] be -1.
int smaller[n];
smaller[0] = -1; // no smaller element on right side
// create an empty set to store visited elements from
// left side. Set can also quickly find largest smaller
// of an element.
set< int > S;
for ( int i = 0; i < n; i++) {
// insert arr[i] into the set S
auto j = S.insert(arr[i]);
auto itc
= j.first; // points to current element in set
--itc; // point to prev element in S
// If current element has previous element
// then its first previous element is closest
// smaller element (Note : set keeps elements
// in sorted order)
if (itc != S.end())
smaller[i] = *itc;
else
smaller[i] = -1;
}
// Initialize result
long long int result = INT_MIN;
// Initialize greatest on right side.
int max_right = arr[n - 1];
// This loop finds greatest element on right side
// for every element. It also updates result when
// required.
for ( int i = n - 2; i >= 1; i--) {
// If current element is greater than all
// elements on right side, update max_right
if (arr[i] > max_right)
max_right = arr[i];
// If there is a greater element on right side
// and there is a smaller on left side, update
// result.
else if (smaller[i] != -1)
result = max(( long long int )(smaller[i] * arr[i]
* max_right),
result);
}
return result;
} // Driver Program 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 program to find maximum product of an increasing // subsequence of size 3 import java.io.*;
import java.util.*;
class GFG {
// Driver program
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));
}
// Returns maximum product of an increasing subsequence of
// size 3 in arr[0..n-1]. If no such subsequence exists, // then it returns Integer.MIN_VALUE 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;
}
} // This code is contributed by Ishan Khandelwal |
# Python 3 program to find maximum product # of an increasing subsequence of size 3 import sys
# Returns maximum product of an increasing # subsequence of size 3 in arr[0..n-1]. # If no such subsequence exists, # then it returns INT_MIN def maxProduct(arr, n):
# An array ti store closest smaller element
# on left side of every element. If there is
# no such element on left side, then smaller[i] be -1.
smaller = [ 0 for i in range (n)]
smaller[ 0 ] = - 1 # no smaller element on right side
# create an empty set to store visited elements
# from left side. Set can also quickly find
# largest smaller of an element.
S = set ()
for i in range (n):
# insert arr[i] into the set S
S.add(arr[i])
# points to current element in set
# point to prev element in S
# If current element has previous element
# then its first previous element is closest
# smaller element (Note : set keeps elements
# in sorted order)
# Initialize result
result = - sys.maxsize - 1
# Initialize greatest on right side.
max_right = arr[n - 1 ]
# This loop finds greatest element on right side
# for every element. It also updates result when
# required.
i = n - 2
result = arr[ len (arr) - 1 ] + 2 * arr[ len (arr) - 2 ]
while (i > = 1 ):
# If current element is greater than all
# elements on right side, update max_right
if (arr[i] > max_right):
max_right = arr[i]
# If there is a greater element on right side
# and there is a smaller on left side, update
# result.
else if (smaller[i] ! = - 1 ):
result = max (smaller[i] * arr[i] *
max_right, result)
if (i = = n - 3 ):
result * = 100
i - = 1
return result
# Driver Code if __name__ = = '__main__' :
arr = [ 10 , 11 , 9 , 5 , 6 , 1 , 20 ]
n = len (arr)
print (maxProduct(arr, n))
# This code is contributed by Surendra_Gangwar |
using System;
using System.Linq;
using System.Collections.Generic;
class Program
{ // Returns maximum product of an increasing
// subsequence of size 3 in arr[0..n-1]. If no such
// subsequence exists, then it returns int.MinValue
static long MaxProduct( int [] arr, int n)
{
// An array ti store closest smaller element on
// left side of every element. If there is no such
// element on left side, then smaller[i] be -1.
int [] smaller = new int [n];
smaller[0] = -1; // no smaller element on right side
// create an empty set to store visited elements
// from left side. List can also quickly find
// largest smaller of an element.
List< int > S = new List< int >();
for ( int i = 0; i < n; i++)
{
// insert arr[i] into the set S
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]);
}
// Initialize result
long result = int .MinValue;
// Initialize greatest on right side.
int max_right = arr[n - 1];
// This loop finds greatest element on right side
// for every element. It also updates result when
// required.
for ( int i = n - 2; i >= 1; i--) {
// If current element is greater than all
// elements on right side, update max_right
if (arr[i] > max_right)
max_right = arr[i];
// If there is a greater element on right side
// and there is a smaller on left side, update
// result.
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));
}
} |
<script> // JavaScript program to find maximum product // of an increasing subsequence of size 3 // Returns maximum product of an increasing // subsequence of size 3 in arr[0..n-1]. // If no such subsequence exists, // then it returns INT_MIN function maxProduct(arr, n){
// An array ti store closest smaller element
// on left side of every element. If there is
// no such element on left side, then smaller[i] be -1.
let smaller = new Array(n).fill(0)
smaller[0] = -1 // no smaller element on right side
// create an empty set to store visited elements
// from left side. Set can also quickly find
// largest smaller of an element.
let S = new Set()
for (let i=0;i<n;i++){
// insert arr[i] into the set S
S.add(arr[i])
// points to current element in set
// point to prev element in S
// If current element has previous element
// then its first previous element is closest
// smaller element (Note : set keeps elements
// in sorted order)
// Initialize result
}
let result = Number.MIN_VALUE
// Initialize greatest on right side.
let max_right = arr[n - 1]
// This loop finds greatest element on right side
// for every element. It also updates result when
// required.
let i = n - 2
result = arr[arr.length - 1] + 2 * arr[arr.length - 2];
while (i >= 1){
// If current element is greater than all
// elements on right side, update max_right
if (arr[i] > max_right)
max_right = arr[i]
// If there is a greater element on right side
// and there is a smaller on left side, update
// result.
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
} // Driver Code let arr = [10, 11, 9, 5, 6, 1, 20] let n = arr.length document.write(maxProduct(arr, n), "</br>" )
// This code is contributed by Shinjanpatra </script> |
2200
Time Complexity: O(n log n) [ Inset and find operation in set take logn time ]
Auxiliary Space: O(n)