Given an array arr[] of size N, consisting of distinct elements, the task is to count the number triplets such that (arr[j] – arr[i]) ? (arr[k] – arr[j]) ? 2 * (arr[j] – arr[i]) and arr[i] < arr[j] < arr[k] (1 ? i, j, k ? N and each of them should be distinct).
Examples:
Input: arr[] = {5, 3, 12, 9, 6}
Output: 4
Explanation: All triplets satisfying the conditions are {3, 5, 9}, {3, 6, 9}, {3, 6, 12}, {6, 9, 12}Input: arr[] = {1, 2, 3}
Output: 1
Naive Approach: The simplest approach is to generate all possible triplets and for each of them, check if it satisfies the given conditions or not.
Time Complexity: O(N3)
Auxiliary Space: O(1)
Efficient Approach: The above approach can be optimized by Binary Search. Follow the steps below to solve the problem:
- Sort the array arr[].
- Initialize a variable, say ans as 0, to store the number of triplets.
-
Iterate over the range [1, N] using a variable i and perform the following steps:
-
Iterate in the range [i+1, N] using the variable j and perform the following steps:
- Initialize X as arr[j] – arr[i].
- Find the lower bound of arr[j]+X using lower_bound and store its index in the variable l.
- Similarly, find the upper bound of arr[j] + 2×X using the default function upper_bound and store its index in the variable r.
- Add r-l to the variable ans.
-
Iterate in the range [i+1, N] using the variable j and perform the following steps:
- After performing the above steps, print ans as the answer.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
int countTriplets( int arr[], int N)
{ // Sort the array
sort(arr, arr + N);
// Stores count of triplets
int l, r, i, j, ans = 0;
// Iterate over the range [1, N]
for (i = 0; i < N; i++) {
// Iterate over the range [i+1, N]
for (j = i + 1; j < N; j++) {
// Required difference
int x = arr[j] - arr[i];
// Find lower bound of arr[j] + x
// and upper bound of arr[j] + 2*x
l = lower_bound(arr, arr + N, arr[j] + x) - arr;
r = upper_bound(arr, arr + N, arr[j] + 2 * x)
- arr;
// Adjust the indexing of arr[j]+2*r
if (r == N || arr[r] != arr[j] + 2 * x)
r -= 1;
// From l to r, count number of
// triplets by using arr[i] and arr[j]
ans += r - l + 1;
}
}
// return main ans
return ans;
} // Driver code int main()
{ int arr[] = { 1, 2, 3 };
int N = sizeof (arr) / sizeof (arr[0]);
int ans = countTriplets(arr, N);
cout << ans;
return 0;
} |
// Java program for the above approach import java.util.Arrays;
class GFG{
public static int countTriplets( int arr[], int N)
{ // Sort the array
Arrays.sort(arr);
// Stores count of triplets
int l, r, i, j, ans = 0 ;
// Iterate over the range [1, N]
for (i = 0 ; i < N; i++)
{
// Iterate over the range [i+1, N]
for (j = i + 1 ; j < N; j++)
{
// Required difference
int x = arr[j] - arr[i];
// Find lower bound of arr[j] + x
// and upper bound of arr[j] + 2*x
l = lower_bound(arr, 0 , arr.length - 1 ,
arr[j] + x);
r = upper_bound(arr, 0 , arr.length - 1 ,
arr[j] + 2 * x);
// Adjust the indexing of arr[j]+2*r
if (r == N || arr[r] != arr[j] + 2 * x)
r -= 1 ;
// From l to r, count number of
// triplets by using arr[i] and arr[j]
ans += r - l + 1 ;
}
}
// Return main ans
return ans;
} public static int upper_bound( int [] arr, int low,
int high, int X)
{ // Base Case
if (low > high)
return low;
// Find the middle index
int mid = low + (high - low) / 2 ;
// If arr[mid] is less than
// or equal to X search in
// right subarray
if (arr[mid] <= X)
{
return upper_bound(arr, mid + 1 , high, X);
}
// If arr[mid] is greater than X
// then search in left subarray
return upper_bound(arr, low, mid - 1 , X);
} public static int lower_bound( int [] arr, int low,
int high, int X)
{ // Base Case
if (low > high)
{
return low;
}
// Find the middle index
int mid = low + (high - low) / 2 ;
// If arr[mid] is greater than
// or equal to X then search
// in left subarray
if (arr[mid] >= X)
{
return lower_bound(arr, low, mid - 1 , X);
}
// If arr[mid] is less than X
// then search in right subarray
return lower_bound(arr, mid + 1 , high, X);
} // Driver code public static void main(String args[])
{ int arr[] = { 1 , 2 , 3 };
int N = arr.length;
int ans = countTriplets(arr, N);
System.out.println(ans);
} } // This code is contributed by gfgking |
# Python3 program for the above approach # Import library to apply # binary search and find bound from bisect import bisect_left
# Function to count triplets # from an array that satisfies # the given conditions def countTriplets(arr, N):
# Sort the array
arr.sort()
# Stores count of triplets
ans = 0
# Iterate over the range [1, N]
for i in range (N):
# Iterate over the range [i+1, N]
for j in range (i + 1 , N):
# Required difference
x = arr[j] - arr[i]
# Find lower bound of arr[j] + x
# and upper bound of arr[j] + 2*x
l = bisect_left(arr, arr[j] + x)
r = bisect_left(arr, arr[j] + 2 * x)
# Adjust the indexing of arr[j]+2*r
if r = = N or arr[r] ! = arr[j] + 2 * x:
r - = 1
# From l to r, count number of
# triplets by using arr[i] and arr[j]
ans + = r - l + 1
# return main ans
return ans
# Driver Code if __name__ = = "__main__" :
# Given Input
arr = [ 1 , 2 , 3 ]
N = len (arr)
# Function Call
ans = countTriplets(arr, N)
print (ans)
|
// C# program for the above approach using System;
class GFG {
static int countTriplets( int [] arr, int N)
{
// Sort the array
Array.Sort(arr);
// Stores count of triplets
int l, r, i, j, ans = 0;
// Iterate over the range [1, N]
for (i = 0; i < N; i++)
{
// Iterate over the range [i+1, N]
for (j = i + 1; j < N; j++)
{
// Required difference
int x = arr[j] - arr[i];
// Find lower bound of arr[j] + x
// and upper bound of arr[j] + 2*x
l = lower_bound(arr, 0, arr.Length - 1,
arr[j] + x);
r = upper_bound(arr, 0, arr.Length - 1,
arr[j] + 2 * x);
// Adjust the indexing of arr[j]+2*r
if (r == N || arr[r] != arr[j] + 2 * x)
r -= 1;
// From l to r, count number of
// triplets by using arr[i] and arr[j]
ans += r - l + 1;
}
}
// Return main ans
return ans;
}
static int upper_bound( int [] arr, int low,
int high, int X)
{
// Base Case
if (low > high)
return low;
// Find the middle index
int mid = low + (high - low) / 2;
// If arr[mid] is less than
// or equal to X search in
// right subarray
if (arr[mid] <= X)
{
return upper_bound(arr, mid + 1, high, X);
}
// If arr[mid] is greater than X
// then search in left subarray
return upper_bound(arr, low, mid - 1, X);
}
static int lower_bound( int [] arr, int low,
int high, int X)
{
// Base Case
if (low > high)
{
return low;
}
// Find the middle index
int mid = low + (high - low) / 2;
// If arr[mid] is greater than
// or equal to X then search
// in left subarray
if (arr[mid] >= X)
{
return lower_bound(arr, low, mid - 1, X);
}
// If arr[mid] is less than X
// then search in right subarray
return lower_bound(arr, mid + 1, high, X);
}
static void Main() {
int [] arr = { 1, 2, 3 };
int N = arr.Length;
int ans = countTriplets(arr, N);
Console.WriteLine(ans);
}
} // This code is contributed by divyeshrabadiya07. |
<script> // JavaScript program for the above approach function countTriplets(arr, N) {
// Sort the array
arr.sort((a, b) => a - b);
// Stores count of triplets
let l, r, i, j, ans = 0;
// Iterate over the range [1, N]
for (i = 0; i < N; i++) {
// Iterate over the range [i+1, N]
for (j = i + 1; j < N; j++) {
// Required difference
let x = arr[j] - arr[i];
// Find lower bound of arr[j] + x
// and upper bound of arr[j] + 2*x
l = lower_bound(arr, 0, arr.length - 1, arr[j] + x);
//console.log(l)
console.log(arr, arr[j] + 2 * x)
r = upper_bound(arr, 0, arr.length - 1, arr[j] + 2 * x);
console.log(r)
// Adjust the indexing of arr[j]+2*r
if (r == N || arr[r] != arr[j] + 2 * x)
r -= 1;
// From l to r, count number of
// triplets by using arr[i] and arr[j]
ans += r - l + 1;
}
}
// return main ans
return ans;
} function upper_bound(arr, low, high, X) {
// Base Case
if (low > high)
return low;
// Find the middle index
let mid = Math.floor(low + (high - low) / 2);
// If arr[mid] is less than
// or equal to X search in
// right subarray
if (arr[mid] <= X) {
return upper_bound(arr, mid + 1, high, X);
}
// If arr[mid] is greater than X
// then search in left subarray
return upper_bound(arr, low, mid - 1, X);
} function lower_bound(arr, low, high, X) {
// Base Case
if (low > high) {
return low;
}
// Find the middle index
let mid = Math.floor(low + (high - low) / 2);
// If arr[mid] is greater than
// or equal to X then search
// in left subarray
if (arr[mid] >= X) {
return lower_bound(arr, low, mid - 1, X);
}
// If arr[mid] is less than X
// then search in right subarray
return lower_bound(arr, mid + 1, high, X);
} // Driver code let arr = [1, 2, 3]; let N = arr.length; let ans = countTriplets(arr, N); document.write(ans); </script> |
1
Time Complexity: O(N2*log(N))
Auxiliary Space: O(1)