从数组中计算三元组,使得 a[j] – a[i] ≤ a[k] – a[j] ≤ 2 * (a[j] – a[i])
给定一个大小为N的数组arr[] ,由不同的元素组成,任务是计算三元组的数量,使得(arr[j] – arr[i]) ≤ (arr[k] – arr[j]) ≤ 2 * (arr[j] – arr[i])和arr[i] < arr[j] < arr[k] ( 1 ≤ i, j, k ≤ N并且它们中的每一个都应该是不同的)。
例子:
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
朴素方法:最简单的方法是生成所有可能的三元组,并为每个三元组检查它是否满足给定条件。
时间复杂度: O(N 3 )
辅助空间: O(1)
高效方法:上述方法可以通过二分搜索进行优化。请按照以下步骤解决问题:
- 对数组arr[]进行排序。
- 初始化一个变量,比如ans为0,以存储三元组的数量。
- 使用变量i迭代范围[1, N]并执行以下步骤:
- 使用变量j在[i+1, N]范围内迭代并执行以下步骤:
- 将X初始化为arr[j] – arr[i] 。
- 使用 lower_bound 找到arr[j]+X的下限并将其索引存储在变量l中。
- 类似地,使用默认函数upper_bound 找到arr[j] + 2×X的上限,并将其索引存储在变量r中。
- 将rl添加到变量ans中。
- 使用变量j在[i+1, N]范围内迭代并执行以下步骤:
- 执行上述步骤后,打印ans作为答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
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
输出
1
时间复杂度: O(N 2 *log(N))
辅助空间: O(1)