Count triplets (i, j, k) in an array of distinct elements such that a[i] a[k] and i < j < k
Last Updated :
06 Feb, 2023
Given an array arr[] consisting of N distinct integers, the task is to count the number of triplets (i, j, k) possible from the array arr[] such that i < j < k and arr[i] < arr[j] > arr[k].
Examples:
Input: arr[] = {2, 3, 1, -1}
Output: 2
Explanation: From the given array, all possible triplets satisfying the property (i, j, k) and arr[i] < arr[j] > arr[k] are:
- (0, 1, 2): arr[0](= 2) < arr[1](= 3) > arr[2](= 1).
- (0, 1, 3): arr[0](= 2) < arr[1](= 3) > arr[3](= -1).
Therefore, the count of triplets is 2.
Input: arr[] = {2, 3, 4, 6, 7, 9, 1, 12, 10, 8}
Output: 41
Naive Approach: The simplest approach to solve the problem is to traverse the given array and for each element arr[i], the product of the count of smaller elements on the left side of arr[i] and the count of smaller elements on the right side of arr[i] gives the count of triplets for the element arr[i] as the middle element. The sum of all the counts obtained for each index is the required number of valid triplets. Time Complexity: O(N2)
Auxiliary Space: O(1)
Efficient Approach: The above approach can also be optimized by finding the count of smaller elements using a Policy-based data structure (PBDS). Follow the steps below to solve the problem:
- Initialize the variable, say ans to 0 that stores the total number of possible pairs.
- Initialize two containers of the Policy-based data structure, say P and Q.
- Initialize a vector of pairs V, where V[i]. first and V[i].second stores the count of smaller elements on the left and the right side of every array element arr[i].
- Traverse the given array and for each element arr[i], update the value of V[i].first as P.order_of_key(arr[i]) and insert arr[i] to set P.
- Traverse the array from right to left and for each element arr[i], update the value of V[i].first as P.order_of_key(arr[i]) and insert arr[i] to set Q.
- Traverse the vector of pairs V and add the value of V[i].first * V[i].second to the variable ans.
- After completing the above steps, print the value of ans as the total number of pairs.
Below is the implementation of the above approach:
C++
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <functional>
#include <iostream>
using namespace __gnu_pbds;
using namespace std;
void findTriplets( int arr[], int n)
{
int ans = 0;
tree< int , null_type, less< int >, rb_tree_tag,
tree_order_statistics_node_update>
p, q;
vector<pair< int , int > > v(n);
for ( int i = 0; i < n; i++) {
int index = p.order_of_key(arr[i]);
v[i].first = index;
p.insert(arr[i]);
}
for ( int i = n - 1; i >= 0; i--) {
int index = q.order_of_key(arr[i]);
v[i].second = index;
q.insert(arr[i]);
}
for ( int i = 0; i < n; i++) {
ans += (v[i].first * v[i].second);
}
cout << ans;
}
int main()
{
int arr[] = { 2, 3, 1, -1 };
int N = sizeof (arr) / sizeof (arr[0]);
findTriplets(arr, N);
return 0;
}
|
Java
import java.util.ArrayList;
import java.util.List;
public class Main
{
public static void findTriplets( int [] arr, int n)
{
int ans = 0 ;
List<Pair<Integer, Integer>> v = new ArrayList<>();
for ( int i = 0 ; i < n; i++) {
int index = 0 ;
for ( int j = 0 ; j < i; j++) {
if (arr[j] < arr[i]) {
index++;
}
}
v.add( new Pair<>(index, 0 ));
}
for ( int i = n - 1 ; i >= 0 ; i--) {
int index = 0 ;
for ( int j = n - 1 ; j > i; j--) {
if (arr[j] < arr[i]) {
index++;
}
}
v.get(i).setValue(index);
}
for ( int i = 0 ; i < n; i++) {
ans += (v.get(i).getKey() * v.get(i).getValue());
}
System.out.println(ans);
}
public static void main(String[] args) {
int [] arr = { 2 , 3 , 1 , - 1 };
int N = arr.length;
findTriplets(arr, N);
}
}
class Pair<K, V> {
private K key;
private V value;
public Pair(K key, V value) {
this .key = key;
this .value = value;
}
public void setKey(K key) {
this .key = key;
}
public void setValue(V value) {
this .value = value;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
}
|
Python3
import bisect
def findTriplets(arr, n):
ans = 0
p = []
q = []
for i in range (n):
index = bisect.bisect_left(p, arr[i])
p.insert(index, arr[i])
for i in range (n - 1 , - 1 , - 1 ):
index = bisect.bisect_left(q, arr[i])
q.insert(index, arr[i])
ans = 0
for i in range (n):
for j in range (i + 1 , n):
for k in range (j + 1 , n):
if arr[i] < arr[j] > arr[k]:
ans + = 1
print (ans)
arr = [ 2 , 3 , 1 , - 1 ]
n = len (arr)
findTriplets(arr, n)
|
C#
using System;
using System.Collections.Generic;
class GFG {
public static void findTriplets( int [] arr, int n)
{
int ans = 0;
List<KeyValuePair< int , int >> v = new List<KeyValuePair< int , int >>();
for ( int i = 0; i < n; i++) {
int index = 0;
for ( int j = 0; j < i; j++) {
if (arr[j] < arr[i]) {
index++;
}
}
v.Add( new KeyValuePair< int , int >(index, 0));
}
for ( int i = n - 1; i >= 0; i--) {
int index = 0;
for ( int j = n - 1; j > i; j--) {
if (arr[j] < arr[i]) {
index++;
}
}
v[i] = new KeyValuePair< int , int >(v[i].Key, index);
}
for ( int i = 0; i < n; i++) {
ans += (v[i].Key * v[i].Value);
}
Console.WriteLine(ans);
}
public static void Main( string [] args) {
int [] arr = { 2, 3, 1, -1 };
int N = arr.Length;
findTriplets(arr, N);
}
}
|
Javascript
function findTriplets(arr, n) {
let ans = 0;
let v = new Array();
for (let i = 0; i < n; i++) {
let index = 0;
for (let j = 0; j < i; j++) {
if (arr[j] < arr[i]) {
index++;
}
}
v.push({ left: index, right: 0 });
}
for (let i = n - 1; i >= 0; i--) {
let index = 0;
for (let j = n - 1; j > i; j--) {
if (arr[j] < arr[i]) {
index++;
}
}
v[i].right = index;
}
for (let i = 0; i < n; i++) {
ans += (v[i].left * v[i].right);
}
console.log(ans);
}
let arr = [2, 3, 1, -1];
let N = arr.length;
findTriplets(arr, N);
|
Time Complexity: O(N * log N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...