Given an array arr[], the task is to return the maximum value of increasing triplet (i, j, k) such that i < j < k and arr[i] < arr[j] < arr[k]. The value of a triplet (i, j, k) is arr[i] - arr[j] + arr[k].
Example:
Input: arr = {1, 2, 3,4, 5}
Output: 4Input: arr = {11, 2, 33, 4, 5}
Output: 0
Approach:
The idea is to use a greedy algorithm approach.
Here’s a step-by-step breakdown:
Edge Case Handling: If the array has less than 3 elements, it returns 0 because it’s impossible to form a triplet.
Right Maximum Array: It creates an array rightMax to store the maximum values from the right for each index. This array is filled from right to left.
set: A set is used to store the elements of the array. It keeps the elements in sorted order.
Main Logic: Iterates over the array from the second element to the second last element. For each element, it finds the element in the set that is just less than the current element. If such an element exists and the maximum value from the right for the current index is greater than the current element, it updates the maximum value with the difference between the element just less than the current element, the current element, and the maximum value from the right. The current element is then inserted into the set. Finally returns the maximum value found.
Steps-by-step approach:
- Initialize a array rightMax of the same size as arr.
- Iterate through arr from the second-to-last element to the first, updating each element of rightMax with the maximum value encountered so far (including the current element).
- Create st and Initialize maxVal:
- Create a set named st to store elements of arr.
- Insert the first element of arr into st.
- Initialize maxVal to 0.
- Iterate through arr (excluding first and last two elements):
- For each element arr[i] from the second element to the second-to-last element:
- Find the element in st that is just less than arr[i] using lower_bound.
- If such an element exists:
- Decrement the iterator to get the element just less than arr[i].
- If rightMax[i + 1] (maximum value from the right) is greater than arr[i]:
- Update maxVal with the maximum value found so far, calculated as the difference between the element just less than arr[i], arr[i], and rightMax[i + 1].
- Insert arr[i] into st.
- For each element arr[i] from the second element to the second-to-last element:
- After iterating through all elements, return the calculated maxVal.
Below is the implementation of the above approach:
#include <bits/stdc++.h>
using namespace std;
int maxTriplet(vector<int>& arr)
{
int n = arr.size();
// Handle edge case where there are less than 3 elements
if (n < 3) {
return 0;
}
// Create a vector to store the maximum values from the
// right
vector<int> rightMax(n);
// Initialize the last element of rightMax with the last
// element of arr
rightMax[n - 1] = arr[n - 1];
// Fill the rightMax array with maximum values from
// right to left
for (int i = n - 2; i >= 0; i--) {
rightMax[i] = max(rightMax[i + 1], arr[i]);
}
// Create a multiset to store the elements of arr
set<int> st;
// Insert the first element of arr into the multiset
st.insert(arr[0]);
// Initialize the maximum value to 0
int maxVal = 0;
// Iterate over the elements of arr from the second
// element to the second last element
for (int i = 1; i < n - 1; i++) {
// Find the element in the multiset that is just
// less than arr[i]
auto iter = st.lower_bound(arr[i]);
// If such an element exists
if (iter != st.begin()) {
// Move the iterator one position back to get
// the element just less than arr[i]
iter--;
// If the maximum value from the right for the
// current index is greater than arr[i]
if (rightMax[i + 1] > arr[i]) {
// Update the maximum value with the
// difference between the element just less
// than arr[i], arr[i], and the maximum
// value from the right
maxVal = max(maxVal, *iter - arr[i]
+ rightMax[i + 1]);
}
}
// Insert the current element into the multiset
st.insert(arr[i]);
}
// Return the maximum value
return maxVal;
}
int main()
{
vector<int> arr = { 1, 2, 3, 4, 5 };
int maxValue = maxTriplet(arr);
cout << maxValue << endl;
return 0;
}
import java.util.TreeSet;
public class Main {
public static int maxTriplet(int[] arr)
{
int n = arr.length;
// Handle edge case where there are less than 3
// elements
if (n < 3) {
return 0;
}
// Create a TreeSet to store the maximum values from
// the right
TreeSet<Integer> rightMax = new TreeSet<>();
// Initialize the last element of rightMax with the
// last element of arr
rightMax.add(arr[n - 1]);
// Fill the rightMax TreeSet with maximum values
// from right to left
for (int i = n - 2; i >= 0; i--) {
rightMax.add(Math.max(rightMax.last(), arr[i]));
}
// Create a TreeSet to store the elements of arr
TreeSet<Integer> st = new TreeSet<>();
// Insert the first element of arr into the TreeSet
st.add(arr[0]);
// Initialize the maximum value to 0
int maxVal = 0;
// Iterate over the elements of arr from the second
// element to the second last element
for (int i = 1; i < n - 1; i++) {
// Find the element in the TreeSet that is just
// less than arr[i]
Integer lowerBound = st.lower(arr[i]);
// If such an element exists
if (lowerBound != null) {
// If the maximum value from the right for
// the current index is greater than arr[i]
if (rightMax.higher(arr[i]) != null) {
// Update the maximum value with the
// difference between the element just
// less than arr[i], arr[i], and the
// maximum value from the right
maxVal = Math.max(
maxVal,
lowerBound - arr[i]
+ rightMax.higher(arr[i]));
}
}
// Insert the current element into the TreeSet
st.add(arr[i]);
}
// Return the maximum value
return maxVal;
}
public static void main(String[] args)
{
int[] arr = { 1, 2, 3, 4, 5 };
int maxValue = maxTriplet(arr);
System.out.println(maxValue);
}
}
// This code is contributed by Ayush Mishra
import bisect
def maxTriplet(arr):
n = len(arr)
# Handle edge case where there are less than 3 elements
if n < 3:
return 0
# Create a list to store the maximum values from the right
right_max = [0] * n
# Initialize the last element of right_max with the last element of arr
right_max[n - 1] = arr[n - 1]
# Fill the right_max list with maximum values from right to left
for i in range(n - 2, -1, -1):
right_max[i] = max(right_max[i + 1], arr[i])
# Create a set to store the elements of arr
st = set()
# Insert the first element of arr into the set
st.add(arr[0])
# Initialize the maximum value to 0
max_val = 0
# Iterate over the elements of arr from the second element to the second last element
for i in range(1, n - 1):
# Find the element in the set that is just less than arr[i]
iter_val = sorted(st)
iter_idx = bisect.bisect_left(iter_val, arr[i])
if iter_idx > 0:
iter_idx -= 1
iter_element = iter_val[iter_idx]
# If the maximum value from the right for the current index is greater than arr[i]
if right_max[i + 1] > arr[i]:
# Update the maximum value with the difference between the element just less than arr[i],
# arr[i], and the maximum value from the right
max_val = max(max_val, iter_element - arr[i] + right_max[i + 1])
# Insert the current element into the set
st.add(arr[i])
# Return the maximum value
return max_val
# Test the function
arr = [1, 2, 3, 4, 5]
max_value = maxTriplet(arr)
print(max_value)
function maxTriplet(arr) {
const n = arr.length;
// Handle edge case where there are less than 3 elements
if (n < 3) {
return 0;
}
// Create a Set to store the maximum values from the right
const rightMax = new Set();
// Initialize the last element of rightMax with the last element of arr
rightMax.add(arr[n - 1]);
// Fill the rightMax Set with maximum values from right to left
for (let i = n - 2; i >= 0; i--) {
rightMax.add(Math.max(...rightMax, arr[i]));
}
// Create a Set to store the elements of arr
const st = new Set();
// Insert the first element of arr into the Set
st.add(arr[0]);
// Initialize the maximum value to 0
let maxVal = 0;
// Iterate over the elements of arr from the second element to the second last element
for (let i = 1; i < n - 1; i++) {
// Find the element in the Set that is just less than arr[i]
const lowerBound = Array.from(st).find(val => val < arr[i]);
// If such an element exists
if (lowerBound !== undefined) {
// If the maximum value from the right for the current index is greater than arr[i]
const higherRightMax = Array.from(rightMax).find(val => val > arr[i]);
if (higherRightMax !== undefined) {
// Update the maximum value with the difference between the element just
//less than arr[i], arr[i], and the maximum value from the right
maxVal = Math.max(
maxVal,
lowerBound - arr[i] + higherRightMax
);
}
}
// Insert the current element into the Set
st.add(arr[i]);
}
// Return the maximum value
return maxVal;
}
// Test the function
const arr = [1, 2, 3, 4, 5];
const maxValue = maxTriplet(arr);
console.log(maxValue);
Output
4
Time Complexity: O(n log n)
Auxiliary Space: O(n)