Given an array of n integers, find the 3 elements such that a[i] < a[j] < a[k] and i < j < k in 0(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 OR 1, 2, 4 OR 2, 3, 4
Explanation: As the array is sorted, for every i, j, k,
where i < j < k, arr[i] < arr[j] < arr[k]
Input: arr[] = {4, 3, 2, 1}
Output: No such triplet exists.
METHOD 1:
Hint: Use Auxiliary Space.
Solution: So, 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, if there is any such element then there exists a triplet that satisfies the criteria.
Approach: This can be solved in a very simple way. To find an element which has an element smaller than itself on its left side of the array, check if that element is the smallest element while traversing the array from the starting index i.e., (0), and to check if there is an element greater than itself on its right side of the array check whether that element is the largest element while traversing from the end of the array i.e., (n-1). If the element is not the smallest element from 0 to that index then it has an element smaller than itself on its left side, and similarly, if the element is not the largest element from that index to the last index then there is a larger element on its right side.
Algorithm
- 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.
- 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.
- 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 <bits/stdc++.h>
using namespace std;
void find3Numbers( int arr[], int n)
{
int max = n - 1;
int min = 0;
int i;
int * smaller = new int [n];
smaller[0] = -1;
for (i = 1; i < n; i++) {
if (arr[i] <= arr[min]) {
min = i;
smaller[i] = -1;
}
else
smaller[i] = min;
}
int * greater = new int [n];
greater[n - 1] = -1;
for (i = n - 2; i >= 0; i--) {
if (arr[i] >= arr[max]) {
max = i;
greater[i] = -1;
}
else
greater[i] = max;
}
for (i = 0; i < n; i++) {
if (smaller[i] != -1 && greater[i] != -1) {
cout << arr[smaller[i]]
<< " " << arr[i] << " "
<< arr[greater[i]];
return ;
}
}
cout << "No such triplet found" ;
delete [] smaller;
delete [] greater;
return ;
}
int main()
{
int arr[] = { 12, 11, 10, 5, 6, 2, 30 };
int n = sizeof (arr) / sizeof (arr[0]);
find3Numbers(arr, n);
return 0;
a greater number on
}
|
C
#include <stdio.h>
void find3Numbers( int arr[], int n)
{
int max = n - 1;
int min = 0;
int i;
int * smaller = new int [n];
smaller[0] = -1;
for (i = 1; i < n; i++) {
if (arr[i] <= arr[min]) {
min = i;
smaller[i] = -1;
}
else
smaller[i] = min;
}
int * greater = new int [n];
greater[n - 1] = -1;
for (i = n - 2; i >= 0; i--) {
if (arr[i] >= arr[max]) {
max = i;
greater[i] = -1;
}
else
greater[i] = max;
}
for (i = 0; i < n; i++) {
if (smaller[i] != -1 && greater[i] != -1) {
printf ( "%d %d %d" , arr[smaller[i]],
arr[i], arr[greater[i]]);
return ;
}
}
printf ( "No such triplet found" );
delete [] smaller;
delete [] greater;
return ;
}
int main()
{
int arr[] = { 12, 11, 10, 5, 6, 2, 30 };
int n = sizeof (arr) / sizeof (arr[0]);
find3Numbers(arr, n);
return 0;
}
|
Java
import java.io.*;
class SortedSubsequence {
static void find3Numbers( int arr[])
{
int n = arr.length;
int max = n - 1 ;
int min = 0 ;
int i;
int [] smaller = new int [n];
smaller[ 0 ] = - 1 ;
for (i = 1 ; i < n; i++) {
if (arr[i] <= arr[min]) {
min = i;
smaller[i] = - 1 ;
}
else
smaller[i] = min;
}
int [] greater = new int [n];
greater[n - 1 ] = - 1 ;
for (i = n - 2 ; i >= 0 ; i--) {
if (arr[i] >= arr[max]) {
max = i;
greater[i] = - 1 ;
}
else
greater[i] = max;
}
for (i = 0 ; i < n; i++) {
if (
smaller[i] != - 1 && greater[i] != - 1 ) {
System.out.print(
arr[smaller[i]] + " " + arr[i]
+ " " + arr[greater[i]]);
return ;
}
}
System.out.println( "No such triplet found" );
return ;
}
public static void main(String[] args)
{
int arr[] = { 12 , 11 , 10 , 5 , 6 , 2 , 30 };
find3Numbers(arr);
}
}
|
Python
def find3numbers(arr):
n = len (arr)
max = n - 1
min = 0
smaller = [ 0 ] * 10000
smaller[ 0 ] = - 1
for i in range ( 1 , n):
if (arr[i] < = arr[ min ]):
min = i
smaller[i] = - 1
else :
smaller[i] = min
greater = [ 0 ] * 10000
greater[n - 1 ] = - 1
for i in range (n - 2 , - 1 , - 1 ):
if (arr[i] > = arr[ max ]):
max = i
greater[i] = - 1
else :
greater[i] = max
for i in range ( 0 , n):
if smaller[i] ! = - 1 and greater[i] ! = - 1 :
print arr[smaller[i]], arr[i], arr[greater[i]]
return
print "No triplet found"
return
arr = [ 12 , 11 , 10 , 5 , 6 , 2 , 30 ]
find3numbers(arr)
|
C#
using System;
class SortedSubsequence {
static void find3Numbers( int [] arr)
{
int n = arr.Length;
int max = n - 1;
int min = 0;
int i;
int [] smaller = new int [n];
smaller[0] = -1;
for (i = 1; i < n; i++) {
if (arr[i] <= arr[min]) {
min = i;
smaller[i] = -1;
}
else
smaller[i] = min;
}
int [] greater = new int [n];
greater[n - 1] = -1;
for (i = n - 2; i >= 0; i--) {
if (arr[i] >= arr[max]) {
max = i;
greater[i] = -1;
}
else
greater[i] = max;
}
for (i = 0; i < n; i++) {
if (smaller[i] != -1 && greater[i] != -1) {
Console.Write(
arr[smaller[i]] + " " + arr[i]
+ " " + arr[greater[i]]);
return ;
}
}
Console.Write( "No such triplet found" );
return ;
}
public static void Main()
{
int [] arr = { 12, 11, 10, 5, 6, 2, 30 };
find3Numbers(arr);
}
}
|
PHP
<?php
function find3Numbers(& $arr , $n )
{
$max = $n - 1;
$min = 0;
$smaller = array_fill (0, $n , NULL);
$smaller [0] = -1;
for ( $i = 1; $i < $n ; $i ++)
{
if ( $arr [ $i ] <= $arr [ $min ])
{
$min = $i ;
$smaller [ $i ] = -1;
}
else
$smaller [ $i ] = $min ;
}
$greater = array_fill (0, $n , NULL);
$greater [ $n - 1] = -1;
for ( $i = $n - 2; $i >= 0; $i --)
{
if ( $arr [ $i ] >= $arr [ $max ])
{
$max = $i ;
$greater [ $i ] = -1;
}
else
$greater [ $i ] = $max ;
}
for ( $i = 0; $i < $n ; $i ++)
{
if ( $smaller [ $i ] != -1 &&
$greater [ $i ] != -1)
{
echo $arr [ $smaller [ $i ]]. " " .
$arr [ $i ] . " " .
$arr [ $greater [ $i ]];
return ;
}
}
printf( "No such triplet found" );
return ;
}
$arr = array (12, 11, 10, 5, 6, 2, 30);
$n = sizeof( $arr );
find3Numbers( $arr , $n );
?>
|
Javascript
<script>
function find3Numbers(arr)
{
let n = arr.length;
let max = n - 1;
let min = 0;
let i;
let smaller = new Array(n);
for (i=0;i<n;i++)
{
smaller[i]=0;
}
smaller[0] = -1;
for (i = 1; i < n; i++) {
if (arr[i] <= arr[min]) {
min = i;
smaller[i] = -1;
}
else
smaller[i] = min;
}
let greater = new Array(n);
for (i=0;i<n;i++)
{
greater[i]=0;
}
greater[n - 1] = -1;
for (i = n - 2; i >= 0; i--) {
if (arr[i] >= arr[max]) {
max = i;
greater[i] = -1;
}
else
greater[i] = max;
}
for (i = 0; i < n; i++) {
if (
smaller[i] != -1 && greater[i] != -1) {
document.write(
arr[smaller[i]] + " " + arr[i]
+ " " + arr[greater[i]]);
return ;
}
}
document.write( "No such triplet found <br>" );
return ;
}
let arr=[12, 11, 10, 5, 6, 2, 30 ]
find3Numbers(arr);
</script>
|
Complexity Analysis
- Time Complexity: O(n). As the array is traveled only once and there are no nested loops, the time complexity will be in the order of n.
- Auxiliary Space: O(n). Since two extra array is needed to store the index of the previous lesser element and next greater element so the space required will also be in the order of n
METHOD 2:
Solution: 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].
Approach: We can think of the problem in three simple terms.
- 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, its easy to find any subsequent element that is greater than it. Thus we have our arr[i] & arr[j].
- Secondly, consider this sequence – {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. And we can also update arr[i] & arr[j] to lower values i.e. -1 & 0 respectively.
- Thirdly, 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.
Algorithm: Iterate over the length of the array. Keep track of the min. As soon as the next iteration has an element greater than min, we have found our arr[j] and the min will be saved as arr[i]. Continue iterating until we find an element arr[k] which is greater than arr[j]. In case the next elements are of lower value, then we update min, arr[i] and arr[j] to these lower values, so as to give us the best chance to find arr[k].
C++
#include <bits/stdc++.h>
using namespace std;
void find3Numbers(vector< int >& nums)
{
if (nums.size() < 3){
cout << "No such triplet found" ;
return ;
}
int seq = 1;
int min_num = nums[0];
int max_seq = INT_MAX;
int store_min = min_num;
for ( int i = 1; i < nums.size(); i++)
{
if (nums[i] == min_num)
continue ;
else if (nums[i] < min_num)
{
min_num = nums[i];
continue ;
}
else if (nums[i] < max_seq) {
max_seq = nums[i];
store_min = min_num;
}
else if (nums[i] > max_seq)
{
cout << "Triplet: " << store_min <<
", " << max_seq << ", " <<
nums[i] << endl;
return ;
}
}
cout << "No such triplet found" ;
}
int main() {
vector< int > nums {1,2,-1,7,5};
find3Numbers(nums);
}
|
Java
import java.io.*;
public class Main
{
public static void find3Numbers( int [] nums)
{
if (nums.length < 3 ){
System.out.print( "No such triplet found" );
return ;
}
int seq = 1 ;
int min_num = nums[ 0 ];
int max_seq = Integer.MIN_VALUE;
int store_min = min_num;
for ( int i = 1 ; i < nums.length; i++)
{
if (nums[i] == min_num)
continue ;
else if (nums[i] < min_num)
{
min_num = nums[i];
continue ;
}
else if (nums[i] < max_seq) {
max_seq = nums[i];
store_min = min_num;
}
else if (nums[i] > max_seq)
{
seq++;
if (seq == 3 )
{
System.out.println( "Triplet: " + store_min +
", " + max_seq + ", " + nums[i]);
return ;
}
max_seq = nums[i];
}
}
System.out.print( "No such triplet found" );
}
public static void main(String[] args)
{
int [] nums = { 1 , 2 ,- 1 , 7 , 5 };
find3Numbers(nums);
}
}
|
Python3
import sys
def find3Numbers(nums):
if ( len (nums) < 3 ):
print ( "No such triplet found" , end = '')
return
seq = 1
min_num = nums[ 0 ]
max_seq = - sys.maxsize - 1
store_min = min_num
for i in range ( 1 , len (nums)):
if (nums[i] = = min_num):
continue
elif (nums[i] < min_num):
min_num = nums[i]
continue
elif (nums[i] < max_seq):
max_seq = nums[i]
store_min = min_num
elif (nums[i] > max_seq):
if seq = = 1 :
store_min = min_num
seq + = 1
if (seq = = 3 ):
print ( "Triplet: " + str (store_min) +
", " + str (max_seq) + ", " +
str (nums[i]))
return
max_seq = nums[i]
print ( "No such triplet found" , end = '')
if __name__ = = '__main__' :
nums = [ 1 , 2 , - 1 , 7 , 5 ]
find3Numbers(nums)
|
C#
using System;
class GFG {
static void find3Numbers( int [] nums)
{
if (nums.Length < 3){
Console.Write( "No such triplet found" );
return ;
}
int seq = 1;
int min_num = nums[0];
int max_seq = Int32.MinValue;
int store_min = min_num;
for ( int i = 1; i < nums.Length; i++)
{
if (nums[i] == min_num)
continue ;
else if (nums[i] < min_num)
{
min_num = nums[i];
continue ;
}
else if (nums[i] < max_seq) {
max_seq = nums[i];
store_min = min_num;
}
else if (nums[i] > max_seq)
{
seq++;
if (seq == 3)
{
Console.WriteLine( "Triplet: " + store_min +
", " + max_seq + ", " + nums[i]);
return ;
}
max_seq = nums[i];
}
}
Console.Write( "No such triplet found" );
}
static void Main() {
int [] nums = {1,2,-1,7,5};
find3Numbers(nums);
}
}
|
Javascript
<script>
function find3Numbers(nums)
{
if (nums.length < 3)
{
document.write( "No such triplet found" );
return ;
}
let seq = 1;
let min_num = nums[0];
let max_seq = Number.MIN_VALUE;
let store_min = min_num;
for (let i = 1; i < nums.length; i++)
{
if (nums[i] == min_num)
continue ;
else if (nums[i] < min_num)
{
min_num = nums[i];
continue ;
}
else if (nums[i] < max_seq)
{
max_seq = nums[i];
store_min = min_num;
}
else if (nums[i] > max_seq)
{
seq++;
if (seq == 3)
{
document.write( "Triplet: " + store_min +
", " + max_seq + ", " +
nums[i]);
return ;
}
max_seq = nums[i];
}
}
document.write( "No such triplet found" );
}
let nums = [1, 2, -1, 7, 5];
find3Numbers(nums);
</script>
|
Complexity Analysis:
Time Complexity: O(n). As the array is traveled only once and there are no nested loops, the time complexity will be in the order of n.
Auxiliary Space: O(1).
Exercise:
- Find a sub-sequence of size 3 such that arr[i] < arr[j] > arr[k].
- Find a sorted sub-sequence of size 4 in linear time
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!