Open In App

Subsequence of size 3 with 3rd greater than the 1st and snaller than 2nd

Last Updated : 23 Jul, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

You are given an array arr of size n, where each element represents the height of a building positioned along the x-axis. Your task is to determine whether it is possible to choose three distinct buildings such that:

  • The third building is taller than the first, and
  • The third building is shorter than the second.

In other words, check if there exist indices i < j < k such that: arr[i] < arr[k] < arr[j].

Examples:

Input: arr[] = [ 4, 7, 11, 5, 13, 2 ]
Output: Yes
Explanation: One possible way is to select the building at indices [0, 1, 3] with heights 4, 7 and 5 respectively.

Input: arr[] = [ 11, 11, 12, 9 ]
Output: No
Explanation: No 3 buildings fit the given condition.

Naive Approach - Three Nested Loops - O(n^3) Time and O(1) Space

We run three nested loops to consider all subsequences of size 3. As soon as we find a triplet that satisfies the given conditions, we return tree.

C++
#include <iostream>
#include <vector>
using namespace std;

bool isPossible(vector<int>& arr) {
    int n = arr.size();
    
    // Check all triplets (i, j, k) such that i < j < k
    // and arr[i] < arr[k] < arr[j]
    for (int i = 0; i < n - 2; i++) {
        for (int j = i + 1; j < n - 1; j++) {
            for (int k = j + 1; k < n; k++) {
                if (arr[i] < arr[k] && arr[k] < arr[j])
                    return true;
            }
        }
    }
    return false;
}

int main() {
    vector<int> arr1 = {4, 7, 11, 5, 13, 2};
    cout << (isPossible(arr1) ? "Yes" : "No") << endl;

    vector<int> arr2 = {11, 11, 12, 9};
    cout << (isPossible(arr2) ? "Yes" : "No") << endl;

    return 0;
}
Java
// Import necessary libraries
import java.util.*;

public class Main {
    static boolean isPossible(int[] arr) {
        int n = arr.length;

        // Check all triplets (i, j, k) such that i < j < k
        // and arr[i] < arr[k] < arr[j]
        for (int i = 0; i < n - 2; i++) {
            for (int j = i + 1; j < n - 1; j++) {
                for (int k = j + 1; k < n; k++) {
                    if (arr[i] < arr[k] && arr[k] < arr[j])
                        return true;
                }
            }
        }
        return false;
    }

    public static void main(String[] args) {
        int[] arr1 = {4, 7, 11, 5, 13, 2};
        System.out.println(isPossible(arr1) ? "Yes" : "No");

        int[] arr2 = {11, 11, 12, 9};
        System.out.println(isPossible(arr2) ? "Yes" : "No");
    }
}
Python
# Define the function to check for triplets

def is_possible(arr):
    n = len(arr)
    # Check all triplets (i, j, k) such that i < j < k
    # and arr[i] < arr[k] < arr[j]
    for i in range(n - 2):
        for j in range(i + 1, n - 1):
            for k in range(j + 1, n):
                if arr[i] < arr[k] < arr[j]:
                    return True
    return False

# Main execution
arr1 = [4, 7, 11, 5, 13, 2]
print("Yes" if is_possible(arr1) else "No")

arr2 = [11, 11, 12, 9]
print("Yes" if is_possible(arr2) else "No")
C#
// Import necessary libraries
using System;
using System.Linq;

public class MainClass {
    static bool IsPossible(int[] arr) {
        int n = arr.Length;

        // Check all triplets (i, j, k) such that i < j < k
        // and arr[i] < arr[k] < arr[j]
        for (int i = 0; i < n - 2; i++) {
            for (int j = i + 1; j < n - 1; j++) {
                for (int k = j + 1; k < n; k++) {
                    if (arr[i] < arr[k] && arr[k] < arr[j])
                        return true;
                }
            }
        }
        return false;
    }

    public static void Main(string[] args) {
        int[] arr1 = {4, 7, 11, 5, 13, 2};
        Console.WriteLine(IsPossible(arr1) ? "Yes" : "No");

        int[] arr2 = {11, 11, 12, 9};
        Console.WriteLine(IsPossible(arr2) ? "Yes" : "No");
    }
}
JavaScript
// Function to check for triplets
function isPossible(arr) {
    const n = arr.length;
    // Check all triplets (i, j, k) such that i < j < k
    // and arr[i] < arr[k] < arr[j]
    for (let i = 0; i < n - 2; i++) {
        for (let j = i + 1; j < n - 1; j++) {
            for (let k = j + 1; k < n; k++) {
                if (arr[i] < arr[k] && arr[k] < arr[j])
                    return true;
            }
        }
    }
    return false;
}

// Main execution
const arr1 = [4, 7, 11, 5, 13, 2];
console.log(isPossible(arr1) ? "Yes" : "No");

const arr2 = [11, 11, 12, 9];
console.log(isPossible(arr2) ? "Yes" : "No");

Output
Yes
No

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

We process the array in reverse while keeping track of the minimum value seen so far from the left (using a prefix minimum array). This helps us identify a possible first building for each current building considered. For the minimum from the right side (or third value), we use a stack helps maintain candidates for the third building in ascending order, allowing constant-time comparisons.

Follow the below given step-by-step approach:

  • If N is less than 3, return "No" as it's not possible to select three buildings.
  • Initialize a prefix minimum array preMin[] such that preMin[i] holds the minimum value among arr[0] to arr[i].
  • Traverse the array from left to right and update preMin[i] = min(preMin[i - 1], arr[i]).
  • Initialize an empty Stack to store building heights in ascending order from the end.
  • Traverse the array from right to left:
    • If arr[i] is greater than preMin[i], it means there is a smaller element before it that can be the first building.
    • While the Stack is not empty and the top of the Stack is less than or equal to preMin[i], pop elements from the Stack.
    • If the Stack is not empty and the top of the Stack is less than arr[i], return "Yes".
    • Push arr[i] onto the Stack.
  • If the traversal ends without finding such a triplet, return "No".

Below is given the implementation:

C++
#include <bits/stdc++.h>
using namespace std;

bool recreationalSpot(vector<int> &arr) {
    int n = arr.size();

    // if there are less than 3 buildings
    if (n < 3) {
        return false;
    }

    // Stores prefix min array
    vector<int> preMin(n);
    preMin[0] = arr[0];
    for (int i = 1; i < n; i++) {
        preMin[i] = min(preMin[i - 1], arr[i]);
    }

    // Stores the element from the
    // ending in increasing order
    stack<int> st;

    // Iterate until j is greater than
    // or equal to 0
    for (int j = n - 1; j >= 0; j--) {

        // If current array element is
        // greater than the prefix min upto j
        if (arr[j] > preMin[j]) {

            // Iterate while st is not
            // empty and top element is
            // less than or equal to preMin[j]
            while (!st.empty() && st.top() <= preMin[j]) {

                // Remove the top element
                st.pop();
            }

            // If st is not empty and top
            // element of the st is less
            // than the current element
            if (!st.empty() && st.top() < arr[j]) {
                return true;
            }

            // Push the arr[j] in st
            st.push(arr[j]);
        }
    }

    // If none of the above case
    // satisfy then return false
    return false;
}

int main() {
    vector<int> arr = { 4, 7, 11, 5, 13, 2 };
    if(recreationalSpot(arr)) {
        cout << "Yes";
    } else {
        cout << "No";
    }
    return 0;
}
Java
import java.util.*;

class GfG {

    static boolean recreationalSpot(List<Integer> arr) {
        int n = arr.size();

        // if there are less than 3 buildings
        if (n < 3) {
            return false;
        }

        // Stores prefix min array
        int[] preMin = new int[n];
        preMin[0] = arr.get(0);
        for (int i = 1; i < n; i++) {
            preMin[i] = Math.min(preMin[i - 1], arr.get(i));
        }

        // Stores the element from the
        // ending in increasing order
        Stack<Integer> st = new Stack<>();

        // Iterate until j is greater than
        // or equal to 0
        for (int j = n - 1; j >= 0; j--) {

            // If current array element is
            // greater than the prefix min upto j
            if (arr.get(j) > preMin[j]) {

                // Iterate while st is not
                // empty and top element is
                // less than or equal to preMin[j]
                while (!st.isEmpty() && st.peek() <= preMin[j]) {

                    // Remove the top element
                    st.pop();
                }

                // If st is not empty and top
                // element of the st is less
                // than the current element
                if (!st.isEmpty() && st.peek() < arr.get(j)) {
                    return true;
                }

                // Push the arr[j] in st
                st.push(arr.get(j));
            }
        }

        // If none of the above case
        // satisfy then return false
        return false;
    }

    public static void main(String[] args) {
        List<Integer> arr = Arrays.asList(4, 7, 11, 5, 13, 2);
        if (recreationalSpot(arr)) {
            System.out.print("Yes");
        } else {
            System.out.print("No");
        }
    }
}
Python
def recreationalSpot(arr):
    n = len(arr)

    # if there are less than 3 buildings
    if n < 3:
        return False

    # Stores prefix min array
    preMin = [0] * n
    preMin[0] = arr[0]
    for i in range(1, n):
        preMin[i] = min(preMin[i - 1], arr[i])

    # Stores the element from the
    # ending in increasing order
    st = []

    # Iterate until j is greater than
    # or equal to 0
    for j in range(n - 1, -1, -1):

        # If current array element is
        # greater than the prefix min upto j
        if arr[j] > preMin[j]:

            # Iterate while st is not
            # empty and top element is
            # less than or equal to preMin[j]
            while st and st[-1] <= preMin[j]:

                # Remove the top element
                st.pop()

            # If st is not empty and top
            # element of the st is less
            # than the current element
            if st and st[-1] < arr[j]:
                return True

            # Push the arr[j] in st
            st.append(arr[j])

    # If none of the above case
    # satisfy then return false
    return False


arr = [4, 7, 11, 5, 13, 2]
if recreationalSpot(arr):
    print("Yes")
else:
    print("No")
C#
using System;
using System.Collections.Generic;

class GfG {

    static bool recreationalSpot(List<int> arr) {
        int n = arr.Count;

        // if there are less than 3 buildings
        if (n < 3) {
            return false;
        }

        // Stores prefix min array
        int[] preMin = new int[n];
        preMin[0] = arr[0];
        for (int i = 1; i < n; i++) {
            preMin[i] = Math.Min(preMin[i - 1], arr[i]);
        }

        // Stores the element from the
        // ending in increasing order
        Stack<int> st = new Stack<int>();

        // Iterate until j is greater than
        // or equal to 0
        for (int j = n - 1; j >= 0; j--) {

            // If current array element is
            // greater than the prefix min upto j
            if (arr[j] > preMin[j]) {

                // Iterate while st is not
                // empty and top element is
                // less than or equal to preMin[j]
                while (st.Count > 0 && st.Peek() <= preMin[j]) {

                    // Remove the top element
                    st.Pop();
                }

                // If st is not empty and top
                // element of the st is less
                // than the current element
                if (st.Count > 0 && st.Peek() < arr[j]) {
                    return true;
                }

                // Push the arr[j] in st
                st.Push(arr[j]);
            }
        }

        // If none of the above case
        // satisfy then return false
        return false;
    }

    static void Main() {
        List<int> arr = new List<int> { 4, 7, 11, 5, 13, 2 };
        if (recreationalSpot(arr)) {
            Console.Write("Yes");
        } else {
            Console.Write("No");
        }
    }
}
JavaScript
function recreationalSpot(arr) {
    let n = arr.length;

    // if there are less than 3 buildings
    if (n < 3) {
        return false;
    }

    // Stores prefix min array
    let preMin = new Array(n);
    preMin[0] = arr[0];
    for (let i = 1; i < n; i++) {
        preMin[i] = Math.min(preMin[i - 1], arr[i]);
    }

    // Stores the element from the
    // ending in increasing order
    let st = [];

    // Iterate until j is greater than
    // or equal to 0
    for (let j = n - 1; j >= 0; j--) {

        // If current array element is
        // greater than the prefix min upto j
        if (arr[j] > preMin[j]) {

            // Iterate while st is not
            // empty and top element is
            // less than or equal to preMin[j]
            while (st.length > 0 && st[st.length - 1] <= preMin[j]) {

                // Remove the top element
                st.pop();
            }

            // If st is not empty and top
            // element of the st is less
            // than the current element
            if (st.length > 0 && st[st.length - 1] < arr[j]) {
                return true;
            }

            // Push the arr[j] in st
            st.push(arr[j]);
        }
    }

    // If none of the above case
    // satisfy then return false
    return false;
}

let arr = [4, 7, 11, 5, 13, 2];
if (recreationalSpot(arr)) {
    console.log("Yes");
} else {
    console.log("No");
}

Output
Yes

Further Optimizations

This problem is mainly a variation of Largest Rectangular Area in a Histogram. We can use the same logic to solve this problem using one for loop and a single stack. We mainly need to find both next smaller and previous smaller for every element and as soon as we find an element that has both, we return true.




132 Geeky Buildings | DSA Problem

Similar Reads