📌  相关文章
📜  数组中的三元组,绝对差小于k

📅  最后修改于: 2021-04-23 06:16:14             🧑  作者: Mango

给定一个由n个元素组成的数组A []和一个整数k 。任务是找到三元组(x,y,k)的数量,其中0 <= x,y,k | A [x] – A [y] | <= k
| A [y] – A [z] | <= k
| A [z] – A [x] | <= k

例子:

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

一个简单的解决方案是运行三个嵌套循环并计算具有给定约束的三胞胎。

一个有效的解决方案基于以下事实:重新排列数组中的元素不会影响答案,因为基本上,我们希望索引x,y,z的顺序递增,而不是A [x],A [y],A [z ]进行排序。假设A [x]在索引y上,A [y]在z上,A [z]在x上,我们仍然可以选择三元组(x,y,z),因为任何两个元素之间的差条件都较小k仍然站立。
现在,要计算满足上述条件的三元组索引(x,y,z)的数量,我们将对给定的数组进行排序。现在,对于每个元素A [i],i> = 2,我们将找到A [i] – k的下界索引,即lb。现在,观察索引lb和i之间的所有元素都小于A [i ],并且所有teo元素之间的差将小于或等于k。因此,索引i处的元素可以视为索引z,我们可以从lb到i – 1中选择任意两个元素。因此,这将使三元组的计数增加i – lb C 2

以下是此方法的实现:

C++
// CPP program to count triplets with difference less
// than k.
#include 
using namespace std;
  
// Return the lower bound i.e smallest index of
// element having value greater or equal to value
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;
}
  
// Return the number of triplet indices satisfies
// the three constraints
int countTriplet(int arr[], int n, int k)
{
    int count = 0;
  
    // sort the array
    sort(arr, arr + n);
  
    // for each element from index 2 to n - 1.
    for (int i = 2; i < n; i++) {
  
        // finding the lower bound of arr[i] - k.
        int cur = binary_lower(arr[i] - k, arr, n);
  
        // If there are at least two elements between
        // lower bound and current element.
        if (cur <= i - 2) {
  
            // increment the count by lb - i C 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
// Java program to count triplets 
// with difference less than k.
import java.io.*;
import java .util.*;
  
class GFG 
{
  
// Return the lower bound i.e 
// smallest index of element 
// having value greater or
// equal to value
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;
}
  
// Return the number of 
// triplet indices satisfies
// the three constraints
static int countTriplet(int arr[], 
                        int n, int k)
{
    int count = 0;
  
    // sort the array
    Arrays.sort(arr);
  
    // for each element from
    // index 2 to n - 1.
    for (int i = 2; i < n; i++) 
    {
  
        // finding the lower 
        // bound of arr[i] - k.
        int cur = binary_lower(arr[i] - k, 
                               arr, n);
  
        // If there are at least two
        // elements between lower
        // bound and current element.
        if (cur <= i - 2) 
        {
  
            // increment the count
            // by lb - i C 2.
            count += ((i - cur) * 
                      (i - cur - 1)) / 2;
        }
    }
    return count;
}
  
// Driver Code
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));
}
}
  
// This code is contributed by anuj_67.


Python 3
# Python 3 program to count 
# triplets with difference less
# than k.
  
# Return the lower bound 
# i.e smallest index of
# element having value greater 
# or equal to value
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
  
# Return the number of triplet 
# indices satisfies
# the three constraints
def countTriplet(arr, n, k):
  
    count = 0
  
    # sort the array
    arr.sort()
  
    # for each element from 
    # index 2 to n - 1.
    for i in range(2, n) :
  
        # finding the lower bound 
        # of arr[i] - k.
        cur = (binary_lower(arr[i] - k
                            , arr, n))
  
        # If there are at least 
        # two elements between
        # lower bound and current element.
        if (cur <= i - 2) :
  
            # increment the count by 
            # lb - i C 2.
            count += ((i - cur) * 
                     (i - cur - 1)) // 2
  
    return count
      
# Driver code        
if __name__ == "__main__":
    arr = [ 1, 1, 2, 2, 3 ]
    k = 1
    n = len(arr)
  
    print(countTriplet(arr, n, k))
  
# This code is contributed by
# ChitraNayal


C#
// C# program to count triplets 
// with difference less than k.
using System;
  
class GFG 
{
  
// Return the lower bound i.e 
// smallest index of element 
// having value greater or
// equal to value
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;
}
  
// Return the number of 
// triplet indices satisfies
// the three constraints
static int countTriplet(int []arr, 
                        int n, int k)
{
    int count = 0;
  
    // sort the array
    Array.Sort(arr);
  
    // for each element from
    // index 2 to n - 1.
    for (int i = 2; i < n; i++) 
    {
  
        // finding the lower 
        // bound of arr[i] - k.
        int cur = binary_lower(arr[i] - k, 
                               arr, n);
  
        // If there are at least two
        // elements between lower
        // bound and current element.
        if (cur <= i - 2) 
        {
  
            // increment the count
            // by lb - i C 2.
            count += ((i - cur) * 
                      (i - cur - 1)) / 2;
        }
    }
    return count;
}
  
// Driver Code
public static void Main () 
{
    int []arr = {1, 1, 2, 2, 3};
    int k = 1;
    int n = arr.Length;
      
    Console.WriteLine(countTriplet(arr, n, k));
}
}
  
// This code is contributed by anuj_67.


输出:

5

复杂度: O(nlogn)