Given an array of positive integers of size n. Find the maximum sum of triplet( ai + aj + ak ) such that 0 <= i < j < k < n and ai < aj < ak.
Input: a[] = 2 5 3 1 4 9
Output: 16
Explanation:
All possible triplets are:-
2 3 4 => sum = 9
2 5 9 => sum = 16
2 3 9 => sum = 14
3 4 9 => sum = 16
1 4 9 => sum = 14
Maximum sum = 16
Simple Approach is to traverse for every triplet with three nested ‘for loops’ and find update the sum of all triplets one by one. Time complexity of this approach is O(n3) which is not sufficient for a larger value of ‘n’.
Better approach is to make further optimization in above approach. Instead of traversing through every triplets with three nested loops, we can traverse through two nested loops. While traversing through each number(assume as middle element(aj)), find maximum number(ai) smaller than aj preceding it and maximum number(ak) greater than aj beyond it. Now after that, update the maximum answer with calculated sum of ai + aj + ak
C++
#include <bits/stdc++.h>
using namespace std;
int maxTripletSum( int arr[], int n)
{
int ans = 0;
for ( int i = 1; i < n - 1; ++i) {
int max1 = 0, max2 = 0;
for ( int j = 0; j < i; ++j)
if (arr[j] < arr[i])
max1 = max(max1, arr[j]);
for ( int j = i + 1; j < n; ++j)
if (arr[j] > arr[i])
max2 = max(max2, arr[j]);
if (max1 && max2)
ans=max(ans,max1+arr[i]+max2);
}
return ans;
}
int main()
{
int arr[] = { 2, 5, 3, 1, 4, 9 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << maxTripletSum(arr, n);
return 0;
}
|
Java
import java.io.*;
import java.math.*;
class GFG {
static int maxTripletSum( int arr[], int n)
{
int ans = 0 ;
for ( int i = 1 ; i < n - 1 ; ++i) {
int max1 = 0 , max2 = 0 ;
for ( int j = 0 ; j < i; ++j)
if (arr[j] < arr[i])
max1 = Math.max(max1, arr[j]);
for ( int j = i + 1 ; j < n; ++j)
if (arr[j] > arr[i])
max2 = Math.max(max2, arr[j]);
if (max1 > 0 && max2 > 0 )
ans = Math.max(ans, max1 + arr[i] + max2);
}
return ans;
}
public static void main(String args[])
{
int arr[] = { 2 , 5 , 3 , 1 , 4 , 9 };
int n = arr.length;
System.out.println(maxTripletSum(arr, n));
}
}
|
Python3
def maxTripletSum(arr, n):
ans = 0
for i in range ( 1 , (n - 1 )):
max1 = 0
max2 = 0
for j in range ( 0 , i):
if (arr[j] < arr[i]):
max1 = max (max1, arr[j])
for j in range ((i + 1 ), n):
if (arr[j] > arr[i]):
max2 = max (max2, arr[j])
if (max1 > 0 and max2 > 0 ):
ans = max (ans, max1 + arr[i] + max2)
return ans
arr = [ 2 , 5 , 3 , 1 , 4 , 9 ]
n = len (arr)
print (maxTripletSum(arr, n))
|
C#
using System;
class GFG {
static int maxTripletSum( int [] arr, int n)
{
int ans = 0;
for ( int i = 1; i < n - 1; ++i)
{
int max1 = 0, max2 = 0;
for ( int j = 0; j < i; ++j)
if (arr[j] < arr[i])
max1 = Math.Max(max1, arr[j]);
for ( int j = i + 1; j < n; ++j)
if (arr[j] > arr[i])
max2 = Math.Max(max2, arr[j]);
if (max1 > 0 && max2 > 0)
ans = Math.Max(ans, max1 + arr[i] + max2);
}
return ans;
}
public static void Main()
{
int [] arr = { 2, 5, 3, 1, 4, 9 };
int n = arr.Length;
Console.WriteLine(maxTripletSum(arr, n));
}
}
|
PHP
<?php
function maxTripletSum( $arr , $n )
{
$ans = 0;
for ( $i = 1; $i < $n - 1; ++ $i )
{
$max1 = 0; $max2 = 0;
for ( $j = 0; $j < $i ; ++ $j )
if ( $arr [ $j ] < $arr [ $i ])
$max1 = max( $max1 , $arr [ $j ]);
for ( $j = $i + 1; $j < $n ; ++ $j )
if ( $arr [ $j ] > $arr [ $i ])
$max2 = max( $max2 , $arr [ $j ]);
if ( $max1 && $max2 )
$ans = max( $ans , $max1 + $arr [ $i ] + $max2 );
}
return $ans ;
}
$arr = array (2, 5, 3, 1, 4, 9);
$n = sizeof( $arr );
echo maxTripletSum( $arr , $n );
?>
|
Javascript
<script>
function maxTripletSum(arr, n)
{
let ans = 0;
for (let i = 1; i < n - 1; ++i) {
let max1 = 0, max2 = 0;
for (let j = 0; j < i; ++j)
if (arr[j] < arr[i])
max1 = Math.max(max1, arr[j]);
for (let j = i + 1; j < n; ++j)
if (arr[j] > arr[i])
max2 = Math.max(max2, arr[j]);
if (max1 && max2)
ans=Math.max(ans,max1+arr[i]+max2);
}
return ans;
}
let arr = [ 2, 5, 3, 1, 4, 9 ];
let n = arr.length;
document.write(maxTripletSum(arr, n));
</script>
|
Output :
16
Time complexity: O(n2)
Auxiliary space: O(1)
Best and efficient approach is use the concept of maximum suffix-array and binary search.
- For finding a maximum number greater than given number beyond it, we can maintain a maximum suffix-array such that for any number(suffixi) it would contain maximum number from index i, i+1, … n-1. Suffix array can be calculated in O(n) time.
- For finding maximum number smaller than the given number preceding it, we can maintain a sorted list of numbers before a given number such we can simply perform a binary search to find a number which is just smaller than the given number. In C++ language, we can perform this by using set associative container of STL library.
C++
#include <bits/stdc++.h>
using namespace std;
int getLowValue(set< int >& lowValue, int & n)
{
auto it = lowValue.lower_bound(n);
--it;
return (*it);
}
int maxTripletSum( int arr[], int n)
{
int maxSuffArr[n + 1];
maxSuffArr[n] = 0;
for ( int i = n - 1; i >= 0; --i)
maxSuffArr[i] = max(maxSuffArr[i + 1], arr[i]);
int ans = 0;
set< int > lowValue;
lowValue.insert(INT_MIN);
for ( int i = 0; i < n - 1; ++i) {
if (maxSuffArr[i + 1] > arr[i]) {
ans = max(ans, getLowValue(lowValue,
arr[i])
+ arr[i] + maxSuffArr[i + 1]);
lowValue.insert(arr[i]);
}
}
return ans;
}
int main()
{
int arr[] = { 2, 5, 3, 1, 4, 9 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << maxTripletSum(arr, n);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG{
public static int maxTripletSum( int arr[], int n)
{
int maxSuffArr[] = new int [n + 1 ];
maxSuffArr[n] = 0 ;
for ( int i = n - 1 ; i >= 0 ; --i)
maxSuffArr[i] = Math.max(maxSuffArr[i + 1 ],
arr[i]);
int ans = 0 ;
TreeSet<Integer> lowValue = new TreeSet<Integer>();
lowValue.add(Integer.MIN_VALUE);
for ( int i = 0 ; i < n - 1 ; ++i)
{
if (maxSuffArr[i + 1 ] > arr[i])
{
ans = Math.max(ans, lowValue.lower(arr[i]) +
arr[i] + maxSuffArr[i + 1 ]);
lowValue.add(arr[i]);
}
}
return ans;
}
public static void main(String[] args)
{
int arr[] = { 2 , 5 , 3 , 1 , 4 , 9 };
int n = 6 ;
System.out.println(maxTripletSum(arr, n));
}
}
|
Python3
import bisect
import sys
def getLowValue(lowValue, n):
it = bisect.bisect_left(lowValue, n)
if it = = 0 :
return - sys.maxsize
else :
return lowValue[it - 1 ]
def maxTripletSum(arr, n):
maxSuffArr = [ 0 ] * (n + 1 )
maxSuffArr[n] = 0
for i in range (n - 1 , - 1 , - 1 ):
maxSuffArr[i] = max (maxSuffArr[i + 1 ], arr[i])
ans = 0
lowValue = [ - sys.maxsize]
for i in range (n - 1 ):
if maxSuffArr[i + 1 ] > arr[i]:
ans = max (ans, getLowValue(lowValue, arr[i])
+ arr[i] + maxSuffArr[i + 1 ])
bisect.insort_left(lowValue, arr[i])
return ans
arr = [ 2 , 5 , 3 , 1 , 4 , 9 ]
n = len (arr)
print (maxTripletSum(arr, n))
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
public class GFG {
public static int maxTripletSum( int [] arr, int n)
{
int [] maxSuffArr = new int [n + 1];
maxSuffArr[n] = 0;
for ( int i = n - 1; i >= 0; --i)
maxSuffArr[i]
= Math.Max(maxSuffArr[i + 1], arr[i]);
int ans = 0;
SortedSet< int > lowValue = new SortedSet< int >();
lowValue.Add( int .MinValue);
for ( int i = 0; i < n - 1; ++i) {
if (maxSuffArr[i + 1] > arr[i]) {
ans = Math.Max(
ans,
lowValue.TakeWhile(x => x < arr[i])
.Last()
+ arr[i] + maxSuffArr[i + 1]);
lowValue.Add(arr[i]);
}
}
return ans;
}
static public void Main()
{
int [] arr = { 2, 5, 3, 1, 4, 9 };
int n = 6;
Console.WriteLine(maxTripletSum(arr, n));
}
}
|
Javascript
function maxTripletSum(arr, n)
{
var maxSuffArr = new Array(n + 1);
maxSuffArr[n] = 0;
for ( var i = n - 1; i >= 0; --i)
maxSuffArr[i] = Math.max(maxSuffArr[i + 1], arr[i]);
var ans = 0;
var lowValue = new Set();
lowValue.add(Number.MIN_SAFE_INTEGER);
for ( var i = 0; i < n - 1; ++i)
{
if (maxSuffArr[i + 1] > arr[i])
{
ans = Math.max(ans, Array.from(lowValue).sort((a,b)=>b-a).find(a => a < arr[i]) + arr[i] + maxSuffArr[i + 1]);
lowValue.add(arr[i]);
}
}
return ans;
}
var arr = [ 2, 5, 3, 1, 4, 9 ];
var n = 6;
console.log(maxTripletSum(arr, n));
|
Output:
16
Time complexity: O(n*log(n))
Auxiliary space: O(n)
This article is contributed by Shubham Bansal. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeksorg. See your article appearing on the GeeksforGeeks main page and help other Geeks
Please Login to comment...