Find number of triplets in array such that a[i]>a[j]>a[k] and i<j<k
Given an array arr of size N. The task is to count the 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 : 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++
// 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 |
C#
// C# implementation of the approach using 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. |
Javascript
<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 triplets function 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
Time Complexity: O(N*LogN)
Auxiliary Space: O(N)
Please Login to comment...