Maximum value of expression (arr[i] + arr[j] * arr[k]) formed from a valid Triplet
Given an array arr[] of N integers. The task is to find the maximum value of (arr[i] + arr[j] * arr[k]) among every triplet (i, j, k) such that arr[i] < arr[j] < arr[k] and i < j < k. If there doesn’t exist any such triplets then print “-1″.
Examples:
Input: arr[]={7, 9, 3, 8, 11, 10}
Output: 106
Explanation:
The valid triplets are:
1) (7, 9, 11), and value of (arr[i] + arr[j] * arr[k]) is 106.
2) (7, 9, 10), and value of (arr[i] + arr[j] * arr[k]) is 97.
3) (7, 8, 10), and value of (arr[i] + arr[j] * arr[k]) is 87.
4) (7, 8, 11), and value of (arr[i] + arr[j] * arr[k]) is 105.
5) (3, 8, 10), and value of (arr[i] + arr[j] * arr[k]) is 83.
6) (3, 8, 11), and value of (arr[i] + arr[j] * arr[k]) is 91.
Therefore, the maximum among the values is 106
Input: arr[]={1, 2, 3}
Output: 7
Naive Approach: The idea is to generate all possible valid triplets (i, j, k) and print the maximum value of arr[i] + arr[j]*arr[k] among all the triplets. Below are the steps:
- Iterate over the array using three nested loops.
- For each valid triplets check if arr[i] < arr[j] < arr[k]. If so then the triplet is valid.
- Find the value of arr[i] + arr[j]*arr[k] for all such triplets if the above condition is true and store it in the variable called value.
- Keep updating the value of above expression to maximum value among all possible triplets.
- If no valid triplet found print -1 Otherwise print the maximum value.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void max_valid_triplet( int A[], int n)
{
int ans = -1;
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++)
{
if (A[i] < A[j] && A[j] < A[k])
{
int value = A[i] + A[j] * A[k];
if (value > ans)
{
ans = value;
}
}
}
}
}
cout << (ans);
}
int main()
{
int arr[] = { 7, 9, 3, 8, 11, 10 };
int n = sizeof (arr) / sizeof (arr[0]);
max_valid_triplet(arr, n);
return 0;
}
|
Java
import java.util.Scanner;
class GFG {
static void
max_valid_triplet( int A[], int n)
{
int ans = - 1 ;
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++) {
if (A[i] < A[j] && A[j] < A[k]) {
int value = A[i] + A[j] * A[k];
if (value > ans) {
ans = value;
}
}
}
}
}
System.out.println(ans);
}
public static void main(String args[])
{
int [] arr = new int [] { 7 , 9 , 3 , 8 , 11 , 10 };
int n = arr.length;
max_valid_triplet(arr, n);
}
}
|
Python3
def max_valid_triplet(A, n):
ans = - 1 ;
for i in range ( 0 , n - 2 ):
for j in range (i + 1 , n - 1 ):
for k in range (j + 1 , n):
if (A[i] < A[j] and A[j] < A[k]):
value = A[i] + A[j] * A[k];
if (value > ans):
ans = value;
print (ans);
if __name__ = = '__main__' :
arr = [ 7 , 9 , 3 , 8 , 11 , 10 ];
n = len (arr);
max_valid_triplet(arr, n);
|
C#
using System;
class GFG{
static void max_valid_triplet( int [] A, int n)
{
int ans = -1;
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++)
{
if (A[i] < A[j] && A[j] < A[k])
{
int value = A[i] + A[j] * A[k];
if (value > ans)
{
ans = value;
}
}
}
}
}
Console.WriteLine(ans);
}
public static void Main(String[] args)
{
int [] arr = new int [] { 7, 9, 3, 8, 11, 10 };
int n = arr.Length;
max_valid_triplet(arr, n);
}
}
|
Javascript
<script>
function max_valid_triplet(A, n)
{
let ans = -1;
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++)
{
if (A[i] < A[j] && A[j] < A[k])
{
let value = A[i] + A[j] * A[k];
if (value > ans)
{
ans = value;
}
}
}
}
}
document.write(ans);
}
let arr = [ 7, 9, 3, 8, 11, 10 ];
let n = arr.length;
max_valid_triplet(arr, n);
</script>
|
Time Complexity: O(N3)
Auxiliary Space: O(1)
Efficient approach: The above method can be optimized by using TreeSet in Java. Below are the steps:
- Create two arrays. One array (left) to store the maximum element on the left side which strictly less than the present element in the original array and another array (right) to store the right side maximum of the present element in the original array as shown in the below image for array arr[] = {7, 9, 3, 8, 11, 10}:
- For the construction of the left array, we use TreeSet in Java, insert the elements into the TreeSet, use the lower() method in TreeSet which will return the greatest element in this set which is strictly less than the given element. If no such element exists in this TreeSet collection then this method returns a NULL.
- The elements in the left array will be arr[i] of the valid triplets and the elements in the right array will be arr[k] of the valid triplet.
- Now, traverse the original array from 1 to N – 1, to select arr[j] for the valid triplet.
- If left[i]!=-1 && right[i]!=-1 then there is a chance for forming triplet.
- Find the value arr[i] + arr[j]*arr[k] for all such valid triplets and update the ans according to the maximum value.
- Print the maximum value if it exists otherwise print “-1”.
Below is the implementation of the above approach:
C++
#include <iostream>
#include <set>
using namespace std;
int max_valid_triplet( int A[], int n)
{
int ans = -1;
int left[n];
int right[n];
int mx = A[n - 1];
for ( int i = n - 2; i >= 0; i--) {
if (mx > A[i])
right[i] = mx;
else
right[i] = -1;
if (mx < A[i])
mx = A[i];
}
set< int > s;
for ( int i = 1; i < n; i++) {
s.insert(A[i - 1]);
auto it = s.lower_bound(A[i]);
if (it == s.begin())
left[i] = -1;
else
left[i] = *(--it);
}
for ( int i = 1; i < n - 1; i++) {
if (left[i] != -1 && right[i] != -1)
ans = max(ans, left[i] + A[i] * right[i]);
}
return ans;
}
int main()
{
int A[] = { 7, 9, 3, 8, 11, 10 };
int n = sizeof (A) / sizeof (A[0]);
cout << max_valid_triplet(A, n) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG {
static int max_valid_triplet( int A[], int n)
{
int ans = - 1 ;
int left[] = new int [n];
int right[] = new int [n];
int max = A[n - 1 ];
for ( int i = n - 2 ; i >= 0 ; i--) {
if (max > A[i])
right[i] = max;
else
right[i] = - 1 ;
if (max < A[i])
max = A[i];
}
TreeSet<Integer> set = new TreeSet<Integer>();
for ( int i = 1 ; i < n; i++) {
set.add(A[i - 1 ]);
Integer result = set.lower(A[i]);
if (result == null )
left[i] = - 1 ;
else
left[i] = result;
}
for ( int i = 1 ; i < n - 1 ; i++) {
if (left[i] != - 1
&& right[i] != - 1 )
ans = Math.max(ans,
left[i] + A[i] * right[i]);
}
return ans;
}
public static void main(String args[])
{
int [] A = new int [] { 7 , 9 , 3 , 8 , 11 , 10 };
int n = A.length;
System.out.println(max_valid_triplet(A, n));
}
}
|
Python3
def max_valid_triplet(A):
n = len (A)
ans = - 1
left = [ 0 ] * n
right = [ 0 ] * n
max_value = A[n - 1 ]
for i in range (n - 2 , - 1 , - 1 ):
if max_value > A[i]:
right[i] = max_value
else :
right[i] = - 1
if max_value < A[i]:
max_value = A[i]
setn = set ()
for i in range ( 1 , n):
setn.add(A[i - 1 ])
result = None
for j in range (A[i - 1 ], - 1 , - 1 ):
if j in setn:
result = j
break
if result is None :
left[i] = - 1
else :
left[i] = result
for i in range ( 1 , n - 1 ):
if left[i] ! = - 1 and right[i] ! = - 1 :
ans = max (ans, left[i] + A[i] * right[i])
return ans
if __name__ = = '__main__' :
A = [ 7 , 9 , 3 , 8 , 11 , 10 ]
print (max_valid_triplet(A))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int max_valid_triplet( int []A, int n)
{
int ans = -1;
int []left = new int [n];
int []right = new int [n];
int max = A[n - 1];
for ( int i = n - 2; i >= 0; i--)
{
if (max > A[i])
right[i] = max;
else
right[i] = -1;
if (max < A[i])
max = A[i];
}
SortedSet< int > set = new SortedSet< int >();
for ( int i = 1; i < n; i++)
{
set .Add(A[i - 1]);
int result = set .Min;
if (result == 0)
left[i] = -1;
else
left[i] = result;
}
for ( int i = 1; i < n - 1; i++)
{
if (left[i] != -1 &&
right[i] != -1)
ans = Math.Max(ans,
left[i] +
A[i] *
right[i]);
}
return ans;
}
public static void Main(String []args)
{
int [] A = new int []{ 7, 9, 3, 8, 11, 10 };
int n = A.Length;
Console.WriteLine(max_valid_triplet(A, n));
}
}
|
Javascript
<script>
function max_valid_triplet(A, n)
{
let ans = -1;
let left = new Array(n);
let right = new Array(n);
for (let i = 0; i < n; i++)
{
left[i] = 0;
right[i] = 0;
}
let max = A[n - 1];
for (let i = n - 2; i >= 0; i--)
{
if (max > A[i])
right[i] = max;
else
right[i] = -1;
if (max < A[i])
max = A[i];
}
let set = new Set();
for (let i = 1; i < n; i++)
{
set.add(A[i - 1]);
let result = Math.min(...Array.from(set));
if (result == 0)
left[i] = -1;
else
left[i] = result;
}
for (let i = 1; i < n - 1; i++)
{
if (left[i] != -1 &&
right[i] != -1)
ans = Math.max(ans, left[i] +
A[i] * right[i]);
}
return ans;
}
let A = [ 7, 9, 3, 8, 11, 10 ];
let n = A.length;
document.write(max_valid_triplet(A, n));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Last Updated :
17 Feb, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...