Skip to content
Related Articles

Related Articles

Improve Article

Count triplets from an array such that a[j] – a[i] ≤ a[k] – a[j] ≤ 2 * (a[j] – a[i])

  • Difficulty Level : Hard
  • Last Updated : 15 Jul, 2021

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.
  • After performing the above steps, print ans as the answer.

Below is the implementation of the above approach: 

C++




// 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




// 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




# 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)

Javascript




<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>
Output
1

Time Complexity: O(N2*log(N))
Auxiliary Space: O(1)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :