Skip to content
Related Articles

Related Articles

Find number of triplets in array such that a[i]>a[j]>a[k] and i<j<k
  • Difficulty Level : Hard
  • Last Updated : 26 Apr, 2021

Given an array arr of size N. The task is to count number of triplets in the array such that a[i]>a[j]>a[k] and i<j<k
Examples: 
 

Input : arr[] = {10, 8, 3, 1} 
Output :
The triplets are: 
1, 3, 8 
1, 3, 10 
1, 8, 10 
3, 8, 10
Input : arr[] = {88, 64, 45, 21, 54} 
Output :
 

Prerequisites: Count inversions 
Approach: 
 

  • Find the greater_left array. greater_left[i] represents the number of elements greater than a[i] and in left side of it ( from 0 to i-1 ).
  • Find the smaller_right array. smaller_right[i] represents the number of elements smaller than a[i] and in right side to it ( from i+1 to n-1 )
  • The final answer will be the sum of the product of greater_left[i] and smaller_right[i] for every index.

Below is the implementation of the above approach: 
 

C++




// CPP program to find triplets
// a[i]>a[j]>a[k] and i<j<k
#include<bits/stdc++.h>
using namespace std;
  
// Updates a node in Binary Index Tree (BIT)
// at given index(i) in BIT.  The given value
// 'val' is added to BITree[i] and
// all of its ancestors in tree.
void update(int BIT[], int n, int i, int val)
{
    for (; i <= n; i += (i & -i)) {
        BIT[i] += val;
    }
}
  
// Returns sum of arr[0..i]. This function
// assumes that the array is preprocessed
// and partial sums of array elements are
// stored in BIT[].
int query(int BIT[], int i)
{
    int sum = 0;
    for (; i > 0; i -= (i & -i)) {
        sum += BIT[i];
    }
    return sum;
}
  
// Converts an array to an array with values from 1 to n
// and relative order of smaller and greater elements
// remains same.  For example, {7, -90, 100, 1} is
// converted to {3, 1, 4 ,2 }
void Convert(int arr[], int n)
{
    int temp[n];
    for (int i = 0; i < n; i++) {
        temp[i] = arr[i];
    }
    sort(temp, temp + n);
  
    for (int i = 0; i < n; i++) {
    arr[i] = lower_bound(temp, temp + n, arr[i]) - temp + 1;
    }
}
  
// Function to find triplets
int getCount(int arr[], int n)
{
    // Decomposition
    Convert(arr, n);
  
    int BIT[n + 1] = { 0 };
    int smaller_right[n + 1] = { 0 };
    int greater_left[n + 1] = { 0 };
 
    // Find all right side smaller elements
    for (int i = n - 1; i >= 0; i--) {
        smaller_right[i] = query(BIT, arr[i]-1);
        update(BIT, n, arr[i], 1);
    }
 
    for (int i = 0; i <= n; i++) {
        BIT[i] = 0;
    }
     
    // Find all left side greater elements
    for (int i = 0; i < n; i++) {
        greater_left[i] = i - query(BIT, arr[i]);
        update(BIT, n, arr[i], 1);
    }
     
    // Find the required answer
    int ans = 0;
    for (int i = 0; i < n; i++) {
        ans += greater_left[i] * smaller_right[i];
    }
     
    // Return the required answer
    return ans;
}
  
// Driver code
int main()
{
    int arr[] = { 7, 3, 4, 3, 3, 1};
 
    int n = sizeof(arr) / sizeof(arr[0]);
     
    cout << getCount(arr, n) << endl;
     
    return 0;
}

Java




import java.io.*;
import java.util.*;
 
class GFG {
     
    public static int lower(int a[], int x)     //Returns leftest index of x in sorted arr else n
     {                                                  //If not present returns index of just greater element
         int n = a.length;
           int l = 0;
        int r = n - 1;
        int ans = n;
        while(l <= r)
        {
            int m = (r - l) / 2 + l;
            if(a[m] >= x)
            {
                ans = m;
                r = m - 1;
            }
            else
            {
                 l = m + 1;
            }
        }
        return ans;
    }
    // Returns sum of arr[0..i]. This function
    // assumes that the array is preprocessed
    // and partial sums of array elements are
    // stored in BIT[].
    public static int query(int BIT[], int i)
    {
        int sum = 0;
        for (; i > 0; i -= (i & -i)) {
            sum += BIT[i];
        }
        return sum;
    }
    // Converts an array to an array with values from 1 to n
    // and relative order of smaller and greater elements
    // remains same.  For example, {7, -90, 100, 1} is
    // converted to {3, 1, 4 ,2 }
    public static void Convert(int arr[], int n)
    {
        int temp[]=new int[n];
        for (int i = 0; i < n; i++) {
            temp[i] = arr[i];
        }
        Arrays.sort(temp);
        for (int i = 0; i < n; i++) {
          arr[i] = lower(temp, arr[i]) + 1;
        }
    }
    // Updates a node in Binary Index Tree (BIT)
    // at given index(i) in BIT.  The given value
    // 'val' is added to BITree[i] and
    // all of its ancestors in tree.
    public static void update(int BIT[], int n, int i, int val)
    {
        for (; i <= n; i += (i & -i)) {
            BIT[i] += val;
        }
    }
    // Function to find triplets
    public static int getCount(int arr[], int n)
    {
        // Decomposition
        Convert(arr, n);
      
        int BIT[] = new int[n+1];
        int smaller_right[] = new int[n+1];
        int greater_left[] = new int[n+1];
        for(int i=0;i<n+1;i++){
            BIT[i]=0;
            smaller_right[i]=0;
            greater_left[i]=0;
        }
        // Find all right side smaller elements
        for (int i = n - 1; i >= 0; i--) {
            smaller_right[i] = query(BIT, arr[i]-1);
            update(BIT, n, arr[i], 1);
        }
     
        for (int i = 0; i <= n; i++) {
            BIT[i] = 0;
        }
         
        // Find all left side greater elements
        for (int i = 0; i < n; i++) {
            greater_left[i] = i - query(BIT, arr[i]);
            update(BIT, n, arr[i], 1);
        }
         
        // Find the required answer
        int ans = 0;
        for (int i = 0; i < n; i++) {
            ans += greater_left[i] * smaller_right[i];
        }
         
        // Return the required answer
        return ans;
    }
    public static void main (String[] args) {
        int arr[] = { 7, 3, 4, 3, 3, 1};
        int n = 6;
        System.out.println(getCount(arr, n));
    }
}
// this code is contributed by Manu Pathria

Python3




# Python3 program to find triplets
# a[i]>a[j]>a[k] and i<j<k
from bisect import bisect_left as lower_bound
 
# Updates a node in Binary Index Tree (BIT)
# at given index(i) in BIT. The given value
# 'val' is added to BITree[i] and
# all of its ancestors in tree.
def update(BIT, n, i, val):
    while i <= n:
        BIT[i] += val
 
        i += (i & -i)
 
# Returns sum of arr[0..i]. This function
# assumes that the array is preprocessed
# and partial sums of array elements are
# stored in BIT[].
def query(BIT, i):
    summ = 0
    while i > 0:
        summ += BIT[i]
 
        i -= (i & -i)
 
    return summ
 
# Converts an array to an array with values
# from 1 to n and relative order of smaller
# and greater elements remains same. For example,
# {7, -90, 100, 1} is converted to {3, 1, 4 ,2 }
def convert(arr, n):
    temp = [0] * n
    for i in range(n):
        temp[i] = arr[i]
 
    temp.sort()
 
    for i in range(n):
        arr[i] = lower_bound(temp, arr[i]) + 1
 
# Function to find triplets
def getCount(arr, n):
 
    # Decomposition
    convert(arr, n)
 
    BIT = [0] * (n + 1)
    smaller_right = [0] * (n + 1)
    greater_left = [0] * (n + 1)
 
    # Find all right side smaller elements
    for i in range(n - 1, -1, -1):
        smaller_right[i] = query(BIT, arr[i] - 1)
        update(BIT, n, arr[i], 1)
 
    for i in range(n + 1):
        BIT[i] = 0
 
    # Find all left side greater elements
    for i in range(n):
        greater_left[i] = i - query(BIT, arr[i])
        update(BIT, n, arr[i], 1)
 
    # Find the required answer
    ans = 0
    for i in range(n):
        ans += greater_left[i] * smaller_right[i]
 
    # Return the required answer
    return ans
 
# Driver Code
if __name__ == "__main__":
    arr = [7, 3, 4, 3, 3, 1]
    n = len(arr)
 
    print(getCount(arr, n))
 
# This code is contributed by
# sanjeev2552

Output: 
 

8

 




My Personal Notes arrow_drop_up
Recommended Articles
Page :