Find Maximum value of Increasing Triplet

Last Updated : 16 May, 2024

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: 4

Input: 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.
  • After iterating through all elements, return the calculated maxVal.

Below is the implementation of the above approach:

C++
#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;
}
Java
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
Python
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)
JavaScript
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)

Comment