Triplets in array with absolute difference less than k
Given an array A[] of n elements and an integer k. The task is to find the number of triplet (x, y, z), where 0 <= x, y, z < n and x, y, z are the index in the array A[] such that:
|A[x] - A[y]| <= k
|A[y] - A[z]| <= k
|A[z] - A[x]| <= k
Examples:
Input : A[] = { 1, 1, 2, 2, 3 }, k = 1
Output : 5
(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3),
(2, 3, 4) are the triplet whose element will
satisfy the above three condition.
Input : A[] = { 1, 2, 3 }, k = 1
Output : 0
A simple solution is to run three nested loops and count triplets with given constraints.
An efficient solution is based on the fact rearranging the elements in the array does not affect the answer because basically, we want index x, y, z to be in increasing order, not A[x], A[y], A[z] to be sorted. Suppose, A[x] is at index y, A[y] at z, A[z] at x, still we can pick the triplet (x, y, z) because the condition of difference between any two elements to be less k still stands.
Now, to calculate the number of triplet indices (x, y, z) that satisfies the above condition, we will sort the given array. Now, for each element A[i], i >= 2, we will find the lower bound index of A[i] – k, say lb. Now, observe all the element between index lb and i are less than A[i] and the difference between any two elements will be less than or equal to k. So, element at index i can be treated as index z and we can choose any two element from lb to i – 1. So, this will increase the count of the triplet by i – lbC2.
Below is the implementation of this approach:
C++
#include <bits/stdc++.h>
using namespace std;
int binary_lower( int value, int arr[], int n)
{
int start = 0;
int end = n - 1;
int ans = -1;
int mid;
while (start <= end) {
mid = (start + end) / 2;
if (arr[mid] >= value) {
end = mid - 1;
ans = mid;
}
else {
start = mid + 1;
}
}
return ans;
}
int countTriplet( int arr[], int n, int k)
{
int count = 0;
sort(arr, arr + n);
for ( int i = 2; i < n; i++) {
int cur = binary_lower(arr[i] - k, arr, n);
if (cur <= i - 2) {
count += ((i - cur) * (i - cur - 1)) / 2;
}
}
return count;
}
int main()
{
int arr[] = { 1, 1, 2, 2, 3 };
int k = 1;
int n = sizeof (arr) / sizeof (arr[0]);
cout << countTriplet(arr, n, k) << endl;
return 0;
}
|
Java
import java.io.*;
import java .util.*;
class GFG
{
static int binary_lower( int value,
int arr[],
int n)
{
int start = 0 ;
int end = n - 1 ;
int ans = - 1 ;
int mid;
while (start <= end)
{
mid = (start + end) / 2 ;
if (arr[mid] >= value)
{
end = mid - 1 ;
ans = mid;
}
else
{
start = mid + 1 ;
}
}
return ans;
}
static int countTriplet( int arr[],
int n, int k)
{
int count = 0 ;
Arrays.sort(arr);
for ( int i = 2 ; i < n; i++)
{
int cur = binary_lower(arr[i] - k,
arr, n);
if (cur <= i - 2 )
{
count += ((i - cur) *
(i - cur - 1 )) / 2 ;
}
}
return count;
}
public static void main (String[] args)
{
int arr[] = { 1 , 1 , 2 , 2 , 3 };
int k = 1 ;
int n = arr.length;
System.out.println(countTriplet(arr, n, k));
}
}
|
Python3
def binary_lower(value, arr, n):
start = 0
end = n - 1
ans = - 1
while (start < = end) :
mid = (start + end) / / 2
if (arr[mid] > = value) :
end = mid - 1
ans = mid
else :
start = mid + 1
return ans
def countTriplet(arr, n, k):
count = 0
arr.sort()
for i in range ( 2 , n) :
cur = (binary_lower(arr[i] - k
, arr, n))
if (cur < = i - 2 ) :
count + = ((i - cur) *
(i - cur - 1 )) / / 2
return count
if __name__ = = "__main__" :
arr = [ 1 , 1 , 2 , 2 , 3 ]
k = 1
n = len (arr)
print (countTriplet(arr, n, k))
|
C#
using System;
class GFG
{
static int binary_lower( int value,
int []arr,
int n)
{
int start = 0;
int end = n - 1;
int ans = -1;
int mid;
while (start <= end)
{
mid = (start + end) / 2;
if (arr[mid] >= value)
{
end = mid - 1;
ans = mid;
}
else
{
start = mid + 1;
}
}
return ans;
}
static int countTriplet( int []arr,
int n, int k)
{
int count = 0;
Array.Sort(arr);
for ( int i = 2; i < n; i++)
{
int cur = binary_lower(arr[i] - k,
arr, n);
if (cur <= i - 2)
{
count += ((i - cur) *
(i - cur - 1)) / 2;
}
}
return count;
}
public static void Main ()
{
int []arr = {1, 1, 2, 2, 3};
int k = 1;
int n = arr.Length;
Console.WriteLine(countTriplet(arr, n, k));
}
}
|
Javascript
<script>
function binary_lower(value, arr, n)
{
var start = 0;
var end = n - 1;
var ans = -1;
var mid;
while (start <= end) {
mid = parseInt((start + end) / 2);
if (arr[mid] >= value) {
end = mid - 1;
ans = mid;
}
else {
start = mid + 1;
}
}
return ans;
}
function countTriplet(arr, n, k)
{
var count = 0;
arr.sort((a,b)=>a-b)
for ( var i = 2; i < n; i++) {
var cur = binary_lower(arr[i] - k, arr, n);
if (cur <= i - 2) {
count += parseInt(((i - cur) * (i - cur - 1)) / 2);
}
}
return count;
}
var arr = [ 1, 1, 2, 2, 3 ];
var k = 1;
var n = arr.length;
document.write( countTriplet(arr, n, k));
</script>
|
Time Complexity: O(nlogn)
Space Complexity: O(1) as no extra space has been used.
Last Updated :
06 Apr, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...