Sorted subsequence of size 3

Last Updated : 9 Apr, 2026

Given an array arr[] of n integers, find the 3 elements such that a[i] < a[j] < a[k] and i < j < k in O(n) time. If there are multiple such triplets, then print any one of them.

Examples:  

Input: arr[] = [12, 11, 10, 5, 6, 2, 30]
Output: 5, 6, 30
Explanation: As 5 < 6 < 30, and they appear in the same sequence in the array

Input: arr[] = [1, 2, 3, 4]
Output: 1, 2, 3
Explanation: As 1 < 2 < 3, and they appear in the same sequence in the array

Input: arr[] = [4, 3, 2, 1]
Output: No such triplet exists.

Try It Yourself
redirect icon

[Naive Approach] - O(n) Time and O(n) Space

The main motive is to find an element which has an element smaller than itself on the left side of the array and an element greater than itself on the right side of the array.

  1. Create an auxiliary array smaller[0..n-1]. smaller[i] stores the index of a number which is smaller than arr[i] and is on the left side. The array contains -1 if there is no such element.
  2. Create another auxiliary array greater[0..n-1]. greater[i] stores the index of a number which is greater than arr[i] and is on the right side of arr[i]. The array contains -1 if there is no such element.
  3. Finally traverse both smaller[] and greater[] and find the index [i] for which both smaller[i] and greater[i] are not equal to -1.
C++
#include <iostream>
using namespace std;

// A function to find a sorted sub-sequence of size 3
vector<int> find3Numbers(vector<int> &arr)
{
    int n = arr.size();

    // Fill smaller[] such that smaller[i] stores the
    // index of a smaller element on the left side
    vector<int> smaller(n, -1);
    int min = 0;
    for (int i = 1; i < n; i++)
    {
        if (arr[i] <= arr[min])
            min = i;
        else
            smaller[i] = min;
    }

    // Fill greater[] such that greater[i] stores the
    // index of a greater element on the right side
    vector<int> greater(n, -1);
    int max = n - 1;
    for (int i = n - 2; i >= 0; i--)
    {
        if (arr[i] >= arr[max])
            max = i;
        else
            greater[i] = max;
    }

    // Find the triplet
    for (int i = 0; i < n; i++)
    {
        if (smaller[i] != -1 && greater[i] != -1)
            return {arr[smaller[i]], arr[i], arr[greater[i]]};
    }

    // If no such triplet is found, return an empty vector
    return {};
}

int main()
{
    vector<int> arr = {12, 11, 10, 5, 6, 2, 30};
    vector<int> res = find3Numbers(arr);
    for (int x : res)
        cout << x << " ";
    return 0;
}
Java
import java.util.*;

class GfG {

    // A function to find a sorted sub-sequence of size 3
    static List<Integer> find3Numbers(int[] arr)
    {
        int n = arr.length;

        // Fill smaller[] such that smaller[i] stores the
        // index of a smaller element on the left side
        int[] smaller = new int[n];
        Arrays.fill(smaller, -1);
        int min = 0;
        for (int i = 1; i < n; i++)
        {
            if (arr[i] <= arr[min])
                min = i;
            else
                smaller[i] = min;
        }

        // Fill greater[] such that greater[i] stores the
        // index of a greater element on the right side
        int[] greater = new int[n];
        Arrays.fill(greater, -1);
        int max = n - 1;
        for (int i = n - 2; i >= 0; i--)
        {
            if (arr[i] >= arr[max])
                max = i;
            else
                greater[i] = max;
        }

        // Find the triplet
        for (int i = 0; i < n; i++)
        {
            if (smaller[i] != -1 && greater[i] != -1)
                return Arrays.asList(arr[smaller[i]], arr[i], arr[greater[i]]);
        }

        // If no such triplet is found, return an empty vector
        return new ArrayList<>();
    }

    public static void main(String[] args)
    {
        int[] arr = {12, 11, 10, 5, 6, 2, 30};
        List<Integer> res = find3Numbers(arr);
        for (int x : res)
            System.out.print(x + " ");
    }
}
Python
# A function to find a sorted sub-sequence of size 3
def find3Numbers(arr):
    n = len(arr)

    # Fill smaller[] such that smaller[i] stores the
    # index of a smaller element on the left side
    smaller = [-1] * n
    min = 0
    for i in range(1, n):
        if arr[i] <= arr[min]:
            min = i
        else:
            smaller[i] = min

    # Fill greater[] such that greater[i] stores the
    # index of a greater element on the right side
    greater = [-1] * n
    max = n - 1
    for i in range(n - 2, -1, -1):
        if arr[i] >= arr[max]:
            max = i
        else:
            greater[i] = max

    # Find the triplet
    for i in range(n):
        if smaller[i] != -1 and greater[i] != -1:
            return [arr[smaller[i]], arr[i], arr[greater[i]]]

    # If no such triplet is found, return an empty vector
    return []


# Driver code
arr = [12, 11, 10, 5, 6, 2, 30]
res = find3Numbers(arr)
for x in res:
    print x, 
C#
using System;
using System.Collections.Generic;

class GfG {

    // A function to find a sorted sub-sequence of size 3
    static List<int> find3Numbers(int[] arr)
    {
        int n = arr.Length;

        // Fill smaller[] such that smaller[i] stores the
        // index of a smaller element on the left side
        int[] smaller = new int[n];
        for (int i = 0; i < n; i++) smaller[i] = -1;
        int min = 0;
        for (int i = 1; i < n; i++)
        {
            if (arr[i] <= arr[min])
                min = i;
            else
                smaller[i] = min;
        }

        // Fill greater[] such that greater[i] stores the
        // index of a greater element on the right side
        int[] greater = new int[n];
        for (int i = 0; i < n; i++) greater[i] = -1;
        int max = n - 1;
        for (int i = n - 2; i >= 0; i--)
        {
            if (arr[i] >= arr[max])
                max = i;
            else
                greater[i] = max;
        }

        // Find the triplet
        for (int i = 0; i < n; i++)
        {
            if (smaller[i] != -1 && greater[i] != -1)
                return new List<int> { arr[smaller[i]], arr[i], arr[greater[i]] };
        }

        // If no such triplet is found, return an empty vector
        return new List<int>();
    }

    static void Main()
    {
        int[] arr = {12, 11, 10, 5, 6, 2, 30};
        List<int> res = find3Numbers(arr);
        foreach (int x in res)
            Console.Write(x + " ");
    }
}
JavaScript
/* A function to find a sorted sub-sequence of size 3 */
function find3Numbers(arr) {
    const n = arr.length;

    // Fill smaller[] such that smaller[i] stores the
    // index of a smaller element on the left side
    const smaller = new Array(n).fill(-1);
    let min = 0;
    for (let i = 1; i < n; i++) {
        if (arr[i] <= arr[min])
            min = i;
        else
            smaller[i] = min;
    }

    // Fill greater[] such that greater[i] stores the
    // index of a greater element on the right side
    const greater = new Array(n).fill(-1);
    let max = n - 1;
    for (let i = n - 2; i >= 0; i--) {
        if (arr[i] >= arr[max])
            max = i;
        else
            greater[i] = max;
    }

    // Find the triplet
    for (let i = 0; i < n; i++) {
        if (smaller[i]!== -1 && greater[i]!== -1)
            return [arr[smaller[i]], arr[i], arr[greater[i]]];
    }

    // If no such triplet is found, return an empty array
    return [];
}

// Driver code
const arr = [12, 11, 10, 5, 6, 2, 30];
const res = find3Numbers(arr);
for (const x of res) {
    console.log(x + " ");
}

Output
5 6 30 

[Expected Approach] - O(n) Time and O(1) Space

First find two elements arr[i] & arr[j] such that arr[i] < arr[j]. Then find a third element arr[k] greater than arr[j]. We can think of the problem in three simple terms.

  1. First we only need to find two elements arr[i] < arr[j] and i < j. This can be done in linear time with just 1 loop over the range of the array. For instance, while keeping track of the min element, it is easy to find any subsequent element that is greater than it. Thus we have our arr[i] & arr[j]. Consider {3, 4, -1, 0, 2}. Initially min is 3, arr[i] is 3 and arr[j] is 4. While iterating over the array we can easily keep track of min and eventually update it to -1, so arr[i] & arr[j] become -1 and 0.
  2. As soon as we have arr[i] & arr[j] values, we can immediately start monitoring the subsequent elements in the same loop for an arr[k] > arr[j]. Thus we can find all three values arr[i] < arr[j] < arr[k] in a single pass over the array.
C++
#include <iostream>
using namespace std;

vector<int> find3Numbers(vector<int> &arr) {
    int n = arr.size();
    if (n < 3)
        return {};

    int first = INT_MAX;
    int second = INT_MAX;
    int prevFirst = INT_MAX;

    // Iterating through the array
    for (int i = 0; i < n; i++) {
        int x = arr[i];

        // Updating first and second smallest numbers
        if (x <= first) {
            first = x;
        } else if (x <= second) {
            second = x;
            prevFirst = first;
        }
        // If a third number greater than first and second is found
        else {
            return {prevFirst, second, x};
        }
    }
    return {};
}

int main() {
    vector<int> arr = {12, 11, 10, 5, 6, 2, 30};

    vector<int> res = find3Numbers(arr);

        for (int x : res)
            cout << x << " ";

    return 0;
}
Java
import java.util.*;

class GfG {

    static List<Integer> find3Numbers(int[] arr) {
        int n = arr.length;
        if (n < 3)
            return new ArrayList<>();

        int first = Integer.MAX_VALUE;
        int second = Integer.MAX_VALUE;
        int prevFirst = Integer.MAX_VALUE;

        // Iterating through the array
        for (int i = 0; i < n; i++) {
            int x = arr[i];

            // Updating first and second smallest numbers
            if (x <= first) {
                first = x;
            } else if (x <= second) {
                second = x;
                prevFirst = first;
            }
            // If a third number greater than first and second is found
            else {
                return Arrays.asList(prevFirst, second, x);
            }
        }
        return new ArrayList<>();
    }

    public static void main(String[] args) {
        int[] arr = {12, 11, 10, 5, 6, 2, 30};

        List<Integer> res = find3Numbers(arr);
       
            for (int x : res)
                System.out.print(x + " ");
        
    }
}
Python
def find3Numbers(arr):
    n = len(arr)
    if n < 3:
        return []

    first = float('inf')
    second = float('inf')
    prevFirst = float('inf')

    # Iterating through the array
    for i in range(n):
        x = arr[i]

        # Updating first and second smallest numbers
        if x <= first:
            first = x
        elif x <= second:
            second = x
            prevFirst = first
        # If a third number greater than first and second is found
        else:
            return [prevFirst, second, x]

    return []

# driver code
arr = [12, 11, 10, 5, 6, 2, 30]
res = find3Numbers(arr)
for x in res:
    print(x, end=" ")
C#
using System;
using System.Collections.Generic;

class GfG {

    static List<int> find3Numbers(int[] arr) {
        int n = arr.Length;
        if (n < 3)
            return new List<int>();

        int first = int.MaxValue;
        int second = int.MaxValue;
        int prevFirst = int.MaxValue;

        // Iterating through the array
        for (int i = 0; i < n; i++) {
            int x = arr[i];

            // Updating first and second smallest numbers
            if (x <= first) {
                first = x;
            } else if (x <= second) {
                second = x;
                prevFirst = first;
            }
            // If a third number greater than first and second is found
            else {
                return new List<int> { prevFirst, second, x };
            }
        }
        return new List<int>();
    }

    static void Main() {
        int[] arr = { 12, 11, 10, 5, 6, 2, 30 };

        List<int> res = find3Numbers(arr);

            foreach (int x in res)
                Console.Write(x + " ");
        
    }
}
JavaScript
function find3Numbers(arr) {
    let n = arr.length;
    if (n < 3)
        return [];

    let first = Number.MAX_VALUE;
    let second = Number.MAX_VALUE;
    let prevFirst = Number.MAX_VALUE;

    // Iterating through the array
    for (let i = 0; i < n; i++) {
        let x = arr[i];

        // Updating first and second smallest numbers
        if (x <= first) {
            first = x;
        } else if (x <= second) {
            second = x;
            prevFirst = first;
        }
        // If a third number greater than first and second is found
        else {
            return [prevFirst, second, x];
        }
    }

    return [];
}

function main() {
    let arr = [12, 11, 10, 5, 6, 2, 30];

    let res = find3Numbers(arr);

        console.log(res.join(" "));
}

main();

Output
5 6 30 
Comment