Open In App

Maximum product of bitonic subsequence of size 3

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of positive integers of size N, the task is to find the maximum product of bitonic subsequence of size 3.
Bitonic Subsequence: subsequence in which elements are first in the increasing order and then decreasing order. Elements in the subsequence are follow this order arr[i] < arr[j] > arr[k] for i < j < k where i, j, k are the index of the given array.
Note: If no such element is found then print -1.

Examples: 

Input: arr[] = {1, 8, 3, 7, 5, 6, 7} 
Output: 126 
Explanation: 
Bitonic subsequences of size 3 are 
{1, 8, 3}, {1, 8, 7}, {1, 8, 5}, {1, 8, 6}, {1, 7, 6}, {3, 7, 6}, {1, 7, 5}, {3, 7, 5}. 
Hence the maximum product of bitonic subsequence is 3*7*6 = 126

Input: arr[] = {1, 8, 3, 7} 
Output: 56 
Explanation: 
Bitonic subsequences of size 3 are 
{1, 8, 3}, {1, 8, 7}, {1, 7, 3}. 
Hence the maximum product of bitonic subsequence is 1*8*7 = 56 
 

Naive Approach:A simple solution is to find the product of all the bitonic subsequences of size 3 and take the maximum among them.

Algorithm:  

  • Initialize ans to -1, such that if there is no such subsequence then the output will be -1.
  • Iterate over the Array with three nested loops with loop variables as i, j, and k for choosing three elements of the array.
  • Check if arr[j] > arr[i] and arr[j] > arr[k] then update the ans with the maximum value between ans and arr[i] * arr[j] * arr[k].

Below is the implementation of the above approach: 

C++




// C++ implementation to find the
// maximum product of the bitonic
// subsequence of size 3
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the maximum
// product of bitonic subsequence
// of size 3
int maxProduct(int arr[], int n){
     
    // Initialize ans to -1 if no such
    // subsequence exist in the array
    int ans = -1;
     
    // Nested loops to choose the three
    // elements of the array
    for (int i = 0; i < n - 2; i++) {
        for (int j = i + 1; j < n - 1; j++) {
            for (int k = j + 1; k < n; k++) {
                 
                // Condition to check if
                // they form a bitonic subsequence
                if (arr[i] < arr[j] &&
                      arr[j] > arr[k])
                    ans = max(
                       ans, arr[i] * arr[j] * arr[k]
                       );
            }
        }
    }
    return ans;
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 8, 3, 7 };
 
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // Function call
    cout << maxProduct(arr, n) << endl;   
}


Java




// Java implementation to find the
// maximum product of the bitonic
// subsequence of size 3
import java.util.*;
 
class GFG{
  
// Function to find the maximum
// product of bitonic subsequence
// of size 3
static int maxProduct(int arr[], int n){
      
    // Initialize ans to -1 if no such
    // subsequence exist in the array
    int ans = -1;
      
    // Nested loops to choose the three
    // elements of the array
    for (int i = 0; i < n - 2; i++) {
        for (int j = i + 1; j < n - 1; j++) {
            for (int k = j + 1; k < n; k++) {
                  
                // Condition to check if
                // they form a bitonic subsequence
                if (arr[i] < arr[j] &&
                      arr[j] > arr[k])
                    ans = Math.max(
                       ans, arr[i] * arr[j] * arr[k]
                       );
            }
        }
    }
    return ans;
}
  
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 1, 8, 3, 7 };
  
    int n = arr.length;
  
    // Function call
    System.out.print(maxProduct(arr, n) +"\n");   
}
}
 
// This code is contributed by 29AjayKumar


Python3




# Python3 implementation to find the
# maximum product of the bitonic
# subsequence of size 3
 
# Function to find the maximum
# product of bitonic subsequence
# of size 3
def maxProduct(arr, n):
 
    # Initialize ans to -1 if no such
    # subsequence exist in the array
    ans = -1
 
    # Nested loops to choose the three
    # elements of the array
    for i in range(n - 2):
        for j in range(i + 1, n - 1):
            for k in range(j + 1, n):
 
                # Condition to check if
                # they form a bitonic subsequence
                if (arr[i] < arr[j] and arr[j] > arr[k]):
                    ans = max(ans, arr[i] * arr[j] * arr[k])
 
    return ans
 
# Driver Code
if __name__ == '__main__':
    arr= [ 1, 8, 3, 7]
 
    n = len(arr)
 
    # Function call
    print(maxProduct(arr, n))
 
# This code is contributed by mohit kumar 29


C#




// C# implementation to find the
// maximum product of the bitonic
// subsequence of size 3
using System;
 
class GFG {
 
     // Function to find the maximum
     // product of bitonic subsequence
    // of size 3
    static int maxProduct(int[] arr, int n)
    {
        // Initialize ans to -1 if no such
        // subsequence exist in the array
        int ans = -1;
          
        // Nested loops to choose the three
        // elements of the array
        for (int i = 0; i < n - 2; i++) {
            for (int j = i + 1; j < n - 1; j++) {
                for (int k = j + 1; k < n; k++) {
                      
                    // Condition to check if
                    // they form a bitonic subsequence
                    if (arr[i] < arr[j] &&
                          arr[j] > arr[k])
                        ans = Math.Max(ans, arr[i] * arr[j] * arr[k]
                           );
                }
            }
        }
        return ans;
    }
     
    // Driver code
    static void Main()
    {
        int[] arr = new int[] { 1, 8, 3, 7 };
        int n = arr.Length;
     
        // Function call to find product
        Console.Write(maxProduct(arr, n));
    }
}
 
// This code is contributed by shubhamsingh


Javascript




<script>
// Java  script implementation to find the
// maximum product of the bitonic
// subsequence of size 3
 
// Function to find the maximum
// product of bitonic subsequence
// of size 3
function maxProduct(arr,n){
     
    // Initialize ans to -1 if no such
    // subsequence exist in the array
    let ans = -1;
     
    // Nested loops to choose the three
    // elements of the array
    for (let i = 0; i < n - 2; i++) {
        for (let j = i + 1; j < n - 1; j++) {
            for (let k = j + 1; k < n; k++) {
                 
                // Condition to check if
                // they form a bitonic subsequence
                if (arr[i] < arr[j] &&
                    arr[j] > arr[k])
                    ans = Math.max(
                    ans, arr[i] * arr[j] * arr[k]
                    );
            }
        }
    }
    return ans;
}
 
// Driver Code
 
    let arr = [ 1, 8, 3, 7 ];
 
    let n = arr.length;
 
    // Function call
    document.write(maxProduct(arr, n) +"<br>");   
 
 
// This code is contributed by Bobby
</script>


Output: 

56

 

Performance Analysis: 

  • Time Complexity: As in the above approach, there is three nested loops to find the maximum product of the bitonic subsequence of size 3, hence the Time Complexity will be O(N3).
  • Auxiliary Space: As in the above approach, there is no extra space used, hence the auxiliary space will be O(1).

Efficient approach: The idea is to find the largest value on the left side and right side of each index which are smaller than the element present at the current index, to do this use a Self Balancing BST and then for every element find the maximum product that can be formed and take the maximum out of those products.
Self-Balancing BST is implemented as set in C++ and TreeSet in Java.

Algorithm:  

  • Declare a self-balancing BST (say s).
  • Declare two new arrays left[] and right[] to store the lower bound for arr[i] in left of that element in left[i] and lower bound of arr[i] in right of that element in right[i].
  • Run a loop from 0 to length – 1 to find the lower bound of arr[i] is left of that element and store it in the left[i].
  • Run a loop from length -1 to 0 to find the lower bound of arr[i] in the right of that element and store it in the right[i].
  • Run a loop from 0 to length – 1 to find the bitonic subsequence that can be formed using that element to get the maximum product using the left[] and right[] array. That is for every element maximum product bitonic subsequence that can be formed is left[i] * right[i] * arr[i].

Below is the implementation of the above approach:  

C++




// C++ implementation to find the
// maximum product of the bitonic
// subsequence of size 3
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the maximum
// product of bitonic subsequence
// of size 3
int maxProduct(int arr[], int n){
     
    // Self Balancing BST
    set<int> s;
    set<int>::iterator it;
     
    // Left array to store the
    // maximum smallest value for
    // every element in left of it
    int Left[n];
 
    // Right array to store the
    // maximum smallest value for
    // every element in right of it
    int Right[n];
 
    // Loop to find the maximum
    // smallest element in left of
    // every element in array
    for (int i = 0; i < n; i++) {
        s.insert(arr[i]);
        it = s.lower_bound(arr[i]);
         
        // Condition to check if there
        // is a maximum smallest element
        if (it != s.begin()) {
            it--;
            Left[i] = *it;
        }
        else {
            Left[i] = -1;
        }
    }
    // Clear Set
    s.clear();
     
    // Loop to find the maximum
    // smallest element in right of
    // every element in array
    for (int i = n - 1; i >= 0; i--) {
        s.insert(arr[i]);
        it = s.lower_bound(arr[i]);
         
        // Condition to check if there
        // is such element exists
        if (it != s.begin()) {
            it--;
            Right[i] = *it;
        }
         
        // If no such element exists.
        else {
            Right[i] = -1;
        }
    }
    int ans = -1;
     
    // Loop to find the maximum product
    // bitonic subsequence of size 3
    for (int i = 0; i < n; i++) {
        if (Left[i] > 0 and Right[i] > 0)
            ans = max(ans, arr[i] * Left[i] * Right[i]);
    }
 
    if (ans < 0) {
        return -1;
    }
    else {
        return ans;
    }
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 8, 3, 7, 5, 6, 7 };
    int n = sizeof(arr) / sizeof(arr[0]);
     
    // Function Call
    cout << maxProduct(arr, n);
}


Java




// Java implementation to find the
// maximum product of the bitonic
// subsequence of size 3
import java.util.*;
import java.lang.System;
 
class GFG{
 
 public static int maxProduct(int arr[],int n)
 {
    // Self Balancing BST
    TreeSet<Integer> ts = new TreeSet<Integer>();
 
    // Left array to store the
    // maximum smallest value for
    // every element in left of it
    int Left[] = new int[n];
  
    // Right array to store the
    // maximum smallest value for
    // every element in right of it
    int Right[] = new int[n];
 
    // Loop to find the maximum
    // smallest element in left of
    // every element in array
    for(int i = 0; i < n; i++)
    {
        ts.add(arr[i]);
 
        if(ts.lower(arr[i]) == null)
            Left[i] = -1;
        else
            Left[i] = ts.lower(arr[i]);
    }
 
    ts.clear();
 
    // Loop to find the maximum
    // smallest element in right of
    // every element in array
    for (int i = n-1; i >= 0; i--)
    {
        ts.add(arr[i]);
 
        if(ts.lower(arr[i]) == null)
            Right[i] = -1;
        else
            Right[i] = ts.lower(arr[i]);
    }
 
    // Loop to find the maximum product
    // bitonic subsequence of size 3
    int ans = 0;
 
    for(int i = 0; i < n; i++)
    {
        //Condition to check whether a sequence is bitonic or not
        if(Left[i] != -1 && Right[i] != -1)
            ans = Math.max(ans, Left[i] * arr[i] * Right[i]);
    }
 
    return ans;
 }
 
 // Driver Code
 public static void main(String args[])
{
    int arr[] = {1, 8, 3, 7, 5, 6, 7 };
 
    int n = arr.length;
 
    int maximum_product = maxProduct(arr,n);
 
    System.out.println(maximum_product);
}
}
 
// This code is contributed by Siddhi.


Python3




import sys
from bisect import bisect_left
 
# Function to find the maximum
# product of bitonic subsequence
# of size 3
 
 
def maxProduct(arr, n):
 
    # Left array to store the
    # maximum smallest value for
    # every element in left of it
    Left = [-1 for i in range(n)]
 
    # Right array to store the
    # maximum smallest value for
    # every element in right of it
    Right = [-1 for i in range(n)]
 
    # Loop to find the maximum
    # smallest element in left of
    # every element in array
    for i in range(1, n):
        max_value = -sys.maxsize
        for j in range(i):
            if arr[j] < arr[i]:
                max_value = max(max_value, arr[j])
        Left[i] = max_value
 
    # Loop to find the maximum
    # smallest element in right of
    # every element in array
    for i in range(n-2, -1, -1):
        max_value = -sys.maxsize
        for j in range(i+1, n):
            if arr[j] < arr[i]:
                max_value = max(max_value, arr[j])
        Right[i] = max_value
 
    ans = -sys.maxsize
 
    # Loop to find the maximum product
    # bitonic subsequence of size 3
    for i in range(n):
        if Left[i] > 0 and Right[i] > 0:
            ans = max(ans, arr[i] * Left[i] * Right[i])
 
    if ans == -sys.maxsize:
        return -1
    else:
        return ans
 
 
# Driver Code
arr = [1, 8, 3, 7, 5, 6, 7]
n = len(arr)
 
# Function Call
print(maxProduct(arr, n))


Javascript




// Javascript implementation to find the
// maximum product of the bitonic
// subsequence of size 3
 
 
function lower_bound(s, x){
     
    let arr = Array.from(s);
    arr.sort();
     
    let l = 0;
    let h = arr.length - 1;
     
    while(l <= h){
        let m = Math.floor((l + h)/2);
         
        if(arr[m] > x) h = m - 1;
        else if(arr[m] < x) l = m + 1;
        else{
            return m;
        }
    }
     
    return l;
}
 
// Function to find the maximum
// product of bitonic subsequence
// of size 3
function maxProduct(arr, n){
     
    // Self Balancing BST
    let s = new Set();
     
    // Left array to store the
    // maximum smallest value for
    // every element in left of it
    let Left = new Array(n);
 
    // Right array to store the
    // maximum smallest value for
    // every element in right of it
    let Right = new Array(n);
 
    // Loop to find the maximum
    // smallest element in left of
    // every element in array
    for (let i = 0; i < n; i++) {
        s.add(arr[i]);
        it = lower_bound(s, arr[i]);
         
        // Condition to check if there
        // is a maximum smallest element
        let temp = Array.from(s);
        temp.sort();
        if (it != 0) {
            Left[i] = temp[it-1];
        }
        else {
            Left[i] = -1;
        }
    }
    // Clear Set
    s.clear();
     
    // Loop to find the maximum
    // smallest element in right of
    // every element in array
    for (let i = n - 1; i >= 0; i--) {
        s.add(arr[i]);
        it = lower_bound(s, arr[i]);
         
         
        // Condition to check if there
        // is such element exists
        let temp = Array.from(s);
        temp.sort();
        if (it != 0) {
            Right[i] = temp[it-1];
        }
         
        // If no such element exists.
        else {
            Right[i] = -1;
        }
    }
    let ans = -1;
     
    // Loop to find the maximum product
    // bitonic subsequence of size 3
    for (let i = 0; i < n; i++) {
        if (Left[i] > 0 && Right[i] > 0)
            ans = Math.max(ans, arr[i] * Left[i] * Right[i]);
    }
 
    if (ans < 0) {
        return -1;
    }
    else {
        return ans;
    }
}
 
// Driver Code
 
let arr = [ 1, 8, 3, 7, 5, 6, 7 ];
let n = arr.length;
 
// Function Call
console.log(maxProduct(arr, n));
 
// The code is contributed by Nidhi goel.


C#




using System;
 
class GFG {
 
    // Function to find the maximum
    // product of bitonic subsequence
    // of size 3
    static int maxProduct(int[] arr, int n)
    {
 
        // Left array to store the
        // maximum smallest value for
        // every element in left of it
        int[] Left = new int[n];
        for (int i = 0; i < n; i++)
            Left[i] = -1;
 
        // Right array to store the
        // maximum smallest value for
        // every element in right of it
        int[] Right = new int[n];
        for (int i = 0; i < n; i++)
            Right[i] = -1;
 
        // Loop to find the maximum
        // smallest element in left of
        // every element in array
        for (int i = 1; i < n; i++) {
            int max_value = int.MinValue;
            for (int j = 0; j < i; j++) {
                if (arr[j] < arr[i])
                    max_value = Math.Max(max_value, arr[j]);
            }
            Left[i] = max_value;
        }
 
        // Loop to find the maximum
        // smallest element in right of
        // every element in array
        for (int i = n - 2; i >= 0; i--) {
            int max_value = int.MinValue;
            for (int j = i + 1; j < n; j++) {
                if (arr[j] < arr[i])
                    max_value = Math.Max(max_value, arr[j]);
            }
            Right[i] = max_value;
        }
 
        int ans = int.MinValue;
 
        // Loop to find the maximum product
        // bitonic subsequence of size 3
        for (int i = 0; i < n; i++) {
            if (Left[i] > 0 && Right[i] > 0)
                ans = Math.Max(ans,
                               arr[i] * Left[i] * Right[i]);
        }
 
        if (ans == int.MinValue)
            return -1;
        else
            return ans;
    }
 
    // Driver Code
    public static void Main()
    {
        int[] arr = { 1, 8, 3, 7, 5, 6, 7 };
        int n = arr.Length;
 
        // Function Call
        Console.WriteLine(maxProduct(arr, n));
    }
}


Output: 

126

 

Performance Analysis: 

  • Time Complexity: O(NlogN).
  • Auxiliary Space: O(N).

 



Last Updated : 25 Mar, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads