Contar trillizos de una array tal que a[j] – a[i] ≤ a[k] – a[j] ≤ 2 * (a[j] – a[i])

Dada una array arr[] de tamaño N, que consta de elementos distintos, la tarea es contar los tripletes de números tales que (arr[j] – arr[i]) ≤ (arr[k] – arr[j]) ≤ 2 * (arr[j] – arr[i]) y arr[i] < arr[j] < arr[k] ( 1 ≤ i, j, k ≤ N y cada uno de ellos debe ser distinto ).

Ejemplos:

Entrada: arr[] = {5, 3, 12, 9, 6}
Salida: 4
Explicación: Todos los tripletes que cumplen las condiciones son {3, 5, 9}, {3, 6, 9}, {3, 6, 12 }, {6, 9, 12}

Entrada: arr[] = {1, 2, 3}
Salida: 1

Enfoque ingenuo: el enfoque más simple es generar todos los tripletes posibles y, para cada uno de ellos, verificar si satisface las condiciones dadas o no. 

Complejidad de Tiempo: O(N 3 )
Espacio Auxiliar: O(1)

Enfoque eficiente: el enfoque anterior se puede optimizar mediante la búsqueda binaria . Siga los pasos a continuación para resolver el problema:

  • Ordene la array arr[] .
  • Inicialice una variable, digamos ans como 0, para almacenar el número de tripletes.
  • Iterar sobre el rango [1, N] usando una variable i y realizar los siguientes pasos:
    • Iterar en el rango [i+1, N] usando la variable j y realizar los siguientes pasos:
      • Inicializa X como arr[j] – arr[i] .
      • Encuentre el límite inferior de arr[j]+X usando lower_bound y almacene su índice en la variable l .
      • De manera similar, encuentre el límite superior de arr[j] + 2×X usando la función predeterminada upper_bound y almacene su índice en la variable r .
      • Agregue rl a la variable ans .
  • Después de realizar los pasos anteriores, escriba ans como respuesta.

A continuación se muestra la implementación del enfoque anterior: 

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>
Producción

1

Complejidad de tiempo: O(N 2 *log(N))
Espacio auxiliar: O(1)

Publicación traducida automáticamente

Artículo escrito por harshitkap00r y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *