Find number of triplets in array such that a[i]>a[j]>a[k] and i<j<k - GeeksforGeeks

22 Dec, 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<kExamples:  
Input : arr[] = {10, 8, 3, 1} Output : 4 The triplets are: 1, 3, 8 1, 3, 10 1, 8, 10 3, 8, 10Input : arr[] = {88, 64, 45, 21, 54} Output : 5  
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++
Java
Python3
C#
Javascript
// 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 tripletsint 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 codeint main(){    int arr[] = { 7, 3, 4, 3, 3, 1};     int n = sizeof(arr) / sizeof(arr[0]);         cout << getCount(arr, n) << endl;         return 0;}
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 program to find triplets# a[i]>a[j]>a[k] and i<j<kfrom 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 tripletsdef 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 Codeif __name__ == "__main__":    arr = [7, 3, 4, 3, 3, 1]    n = len(arr)     print(getCount(arr, n)) # This code is contributed by# sanjeev2552
// C# implementation of the approachusing System; 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];    }    Array.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;  }   // Driver code  public static void Main ()  {    int[] arr = { 7, 3, 4, 3, 3, 1};    int n = 6;    Console.WriteLine(getCount(arr, n));   }} // This code is contributed by target_2.
<script> // JavaScript program to find triplets// a[i]>a[j]>a[k] and i<j<k  // 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.function update(BIT, n, i, 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[].function query(BIT, i) {    let sum = 0;    for (; i > 0; i -= (i & -i)) {        sum += BIT[i];    }    return sum;} //Returns leftest index of x in sorted arr else n//If not present returns index of just greater element function lower(a, x) {    let n = a.length;    let l = 0;    let r = n - 1;    let ans = n;    while (l <= r) {        let m = Math.floor((r - l) / 2) + l;        if (a[m] >= x) {            ans = m;            r = m - 1;        }        else {            l = m + 1;        }    }    return ans;} // 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 }function Convert(arr, n) {    let temp = new Array(n);    for (let i = 0; i < n; i++) {        temp[i] = arr[i];    }    temp.sort((a, b) => a - b);     for (let i = 0; i < n; i++) {        arr[i] = lower(temp, arr[i]) + 1;    }} // Function to find tripletsfunction getCount(arr, n) {    // Decomposition    Convert(arr, n);     let BIT = new Array(n + 1).fill(0);    let smaller_right = new Array(n + 1).fill(0);    let greater_left = new Array(n + 1).fill(0);     // Find all right side smaller elements    for (let i = n - 1; i >= 0; i--) {        smaller_right[i] = query(BIT, arr[i] - 1);        update(BIT, n, arr[i], 1);    }     for (let i = 0; i <= n; i++) {        BIT[i] = 0;    }     // Find all left side greater elements    for (let i = 0; i < n; i++) {        greater_left[i] = i - query(BIT, arr[i]);        update(BIT, n, arr[i], 1);    }     // Find the required answer    let ans = 0;    for (let i = 0; i < n; i++) {        ans += greater_left[i] * smaller_right[i];    }     // Return the required answer    return ans;} // Driver code let arr = [7, 3, 4, 3, 3, 1]; let n = arr.length; document.write(getCount(arr, n) + "<br>");  // This code is contributed by _saurabh_jaiswal </script>
Output:  
8
 
Akanksha_Rai
sanjeev2552
manupathria
_saurabh_jaiswal
target_2
Constructive Algorithms
prefix
Suffix-Array
Arrays
Arrays
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Maximum and minimum of an array using minimum number of comparisons
Stack Data Structure (Introduction and Program)
Top 50 Array Coding Problems for Interviews
Multidimensional Arrays in Java
Introduction to Arrays
Linear Search
Python | Using 2D arrays/lists the right way
Linked List vs Array
Queue | Set 1 (Introduction and Array Implementation)
Find the Missing Number