Open In App

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

Last Updated : 28 Jul, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

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)


C#




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


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)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads